// DUCK_PUBLIC_SURROGATE_BENCHMARK
// Public synthetic bool output only; no production seed, generator, or digest.
// Output here is not asserted to be any generated input matrices' product.
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
#include <x86intrin.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#ifndef DUCK_SHA256_HPP
#define DUCK_SHA256_HPP
#include <stddef.h>
#include <stdint.h>
#include <string.h>
// Portable SHA-256; input is the exact byte sequence, with no native-word hashing.
namespace duck_sha256 {
static inline uint32_t rotate(uint32_t x,unsigned n) {return (x>>n)|(x<<(32-n));}
static void compress(uint32_t h[8],const unsigned char block[64]) {
static const uint32_t k[64]={
0x428a2f98u,0x71374491u,0xb5c0fbcfu,0xe9b5dba5u,0x3956c25bu,0x59f111f1u,0x923f82a4u,0xab1c5ed5u,
0xd807aa98u,0x12835b01u,0x243185beu,0x550c7dc3u,0x72be5d74u,0x80deb1feu,0x9bdc06a7u,0xc19bf174u,
0xe49b69c1u,0xefbe4786u,0x0fc19dc6u,0x240ca1ccu,0x2de92c6fu,0x4a7484aau,0x5cb0a9dcu,0x76f988dau,
0x983e5152u,0xa831c66du,0xb00327c8u,0xbf597fc7u,0xc6e00bf3u,0xd5a79147u,0x06ca6351u,0x14292967u,
0x27b70a85u,0x2e1b2138u,0x4d2c6dfcu,0x53380d13u,0x650a7354u,0x766a0abbu,0x81c2c92eu,0x92722c85u,
0xa2bfe8a1u,0xa81a664bu,0xc24b8b70u,0xc76c51a3u,0xd192e819u,0xd6990624u,0xf40e3585u,0x106aa070u,
0x19a4c116u,0x1e376c08u,0x2748774cu,0x34b0bcb5u,0x391c0cb3u,0x4ed8aa4au,0x5b9cca4fu,0x682e6ff3u,
0x748f82eeu,0x78a5636fu,0x84c87814u,0x8cc70208u,0x90befffau,0xa4506cebu,0xbef9a3f7u,0xc67178f2u};
uint32_t w[64];
for(unsigned i=0;i<16;++i)w[i]=(uint32_t(block[4*i])<<24)|(uint32_t(block[4*i+1])<<16)|(uint32_t(block[4*i+2])<<8)|block[4*i+3];
for(unsigned i=16;i<64;++i){uint32_t a=w[i-15],b=w[i-2];w[i]=w[i-16]+(rotate(a,7)^rotate(a,18)^(a>>3))+w[i-7]+(rotate(b,17)^rotate(b,19)^(b>>10));}
uint32_t a=h[0],b=h[1],c=h[2],d=h[3],e=h[4],f=h[5],g=h[6],v=h[7];
for(unsigned i=0;i<64;++i){
uint32_t t1=v+(rotate(e,6)^rotate(e,11)^rotate(e,25))+((e&f)^(~e&g))+k[i]+w[i];
uint32_t t2=(rotate(a,2)^rotate(a,13)^rotate(a,22))+((a&b)^(a&c)^(b&c));
v=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;
}
h[0]+=a;h[1]+=b;h[2]+=c;h[3]+=d;h[4]+=e;h[5]+=f;h[6]+=g;h[7]+=v;
}
inline void digest(const void*data,size_t length,unsigned char out[32]) {
uint32_t h[8]={0x6a09e667u,0xbb67ae85u,0x3c6ef372u,0xa54ff53au,0x510e527fu,0x9b05688cu,0x1f83d9abu,0x5be0cd19u};
const unsigned char*p=(const unsigned char*)data;
size_t whole=length/64;
for(size_t i=0;i<whole;++i)compress(h,p+64*i);
unsigned char tail[128]={};size_t remain=length%64;
if(remain)memcpy(tail,p+64*whole,remain);
tail[remain]=0x80;size_t padded=remain<56?64:128;
uint64_t bits=uint64_t(length)*8;
for(unsigned i=0;i<8;++i)tail[padded-1-i]=(unsigned char)(bits>>(8*i));
compress(h,tail);if(padded==128)compress(h,tail+64);
for(unsigned i=0;i<8;++i)for(unsigned j=0;j<4;++j)out[4*i+j]=(unsigned char)(h[i]>>(24-8*j));
}
}
#endif
int main(){
constexpr size_t output_bytes=1073741824ULL;
unsigned char*output=nullptr;
if(posix_memalign((void**)&output,4096,output_bytes))return 1;
const unsigned char pattern[64]={0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1};
_mm_lfence();const unsigned long long t0=__rdtsc();
for(size_t i=0;i<output_bytes;i+=64)memcpy(output+i,pattern,64);
_mm_lfence();const unsigned long long tc=__rdtsc();
const unsigned char expected_digest[32]={0xd0,0x57,0xcf,0x8c,0x46,0x1f,0xf8,0xa8,0x70,0x98,0xe3,0x6a,0x61,0x0a,0xc8,0xb3,0x0b,0x25,0x5c,0x91,0x12,0xe5,0xcb,0xbe,0xa1,0x40,0x67,0x6c,0x99,0xbd,0x17,0x11};
unsigned char actual_digest[32];
duck_sha256::digest(output,output_bytes,actual_digest);
_mm_lfence();const unsigned long long th=__rdtsc();
if(memcmp(actual_digest,expected_digest,32))return 2;
printf("output_setup_ticks=%llu hash_ticks=%llu bytes=%zu\n",tc-t0,th-tc,output_bytes);
free(output);return 0;
}
| Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
| Testcase #1 | 5.186 s | 1024 MB + 20 KB | Accepted | Score: 100 | 显示更多 |