init: v1.0.0
This commit is contained in:
+1044
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
package sm3
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
var useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
|
||||
|
||||
//go:noescape
|
||||
func blockAsmAVX2(dig *digest, p []byte)
|
||||
|
||||
var block func(dig *digest, p []byte)
|
||||
|
||||
func init() {
|
||||
if useAVX2 {
|
||||
block = blockAsmAVX2
|
||||
} else {
|
||||
block = blockGeneric
|
||||
}
|
||||
}
|
||||
|
||||
// BlockAsmAVX2 export blockAsmAVX2 for test
|
||||
var BlockAsmAVX2 = blockAsmAVX2
|
||||
|
||||
// BlockGeneric export blockGeneric for test
|
||||
var BlockGeneric = blockGeneric
|
||||
@@ -0,0 +1,598 @@
|
||||
#include "textflag.h"
|
||||
|
||||
// SM3 block routine.
|
||||
//
|
||||
// No "function stitching" now.
|
||||
//
|
||||
// The algorithm is detailed in GB/T 32905-2016
|
||||
|
||||
// FFt(x,y,z) = GGt(x,y,z) = Parity(x,y,z) for 0 <= t <= 15
|
||||
// FFt(x,y,z) = Maj(x,y,z) for 15 <= t <= 63
|
||||
// GGt(x,y,z) = Ch(x,y,z) for 15 <= t <= 63
|
||||
//
|
||||
// Wt = Mt; for 0 <= t <= 15
|
||||
// Wt = P1(Wt-16 xor Wt-9 xor ROTL(Wt-3,15))
|
||||
// xor ROTL(Wi-13, 7) xor Wt-6 for 16 <= t <= 67
|
||||
// W't = Wt xor Wt+4 for 0 <= t <= 63.
|
||||
//
|
||||
// a = V0
|
||||
// b = V1
|
||||
// c = V2
|
||||
// d = V3
|
||||
// e = V4
|
||||
// f = V5
|
||||
// g = V6
|
||||
// h = V7
|
||||
//
|
||||
// for t = 0 to 63 {
|
||||
// SS1 = ROTL(ROTL(a,12) + E + ROTL(Tt, t mod 32), 7)
|
||||
// SS2 = SS1 xor ROTL(a,12)
|
||||
// TT1 = FFt(a,b,c) + D + SS2 +W't
|
||||
// TT2 = GGt(e,f,g) + h + SS1 +Wt
|
||||
// d = c
|
||||
// c = ROTL(b,9)
|
||||
// b = a
|
||||
// a = TT1
|
||||
// h = g
|
||||
// g = ROTL(f,19)
|
||||
// f = e
|
||||
// e = P0(TT2)
|
||||
// }
|
||||
//
|
||||
// V0 = a xor V0
|
||||
// V1 = b xor V1
|
||||
// V2 = c xor V2
|
||||
// V3 = d xor V3
|
||||
// V4 = e xor V4
|
||||
// V5 = f xor V5
|
||||
// V6 = g xor V6
|
||||
// V7 = h xor V7
|
||||
|
||||
// Definitions for AVX2 version
|
||||
|
||||
// xorm (mem), reg
|
||||
// Xor reg to mem using reg-mem xor and store
|
||||
#define xorm(P1, P2) \
|
||||
XORL P2, P1; \
|
||||
MOVL P1, P2
|
||||
|
||||
#define XDWORD0 Y4
|
||||
#define XDWORD1 Y5
|
||||
#define XDWORD2 Y6
|
||||
#define XDWORD3 Y7
|
||||
|
||||
#define XWORD0 X4
|
||||
#define XWORD1 X5
|
||||
#define XWORD2 X6
|
||||
#define XWORD3 X7
|
||||
|
||||
#define XTMP0 Y0
|
||||
#define XTMP1 Y1
|
||||
#define XTMP2 Y2
|
||||
#define XTMP3 Y3
|
||||
#define XTMP4 Y8
|
||||
#define XTMP5 Y11
|
||||
|
||||
#define XFER Y9
|
||||
|
||||
#define BYTE_FLIP_MASK Y13 // mask to convert LE -> BE
|
||||
#define X_BYTE_FLIP_MASK X13
|
||||
|
||||
#define NUM_BYTES DX
|
||||
#define INP DI
|
||||
|
||||
#define CTX SI // Beginning of digest in memory (a, b, c, ... , h)
|
||||
|
||||
#define a AX
|
||||
#define b BX
|
||||
#define c CX
|
||||
#define d R8
|
||||
#define e DX
|
||||
#define f R9
|
||||
#define g R10
|
||||
#define h R11
|
||||
|
||||
#define old_h R11
|
||||
|
||||
#define TBL BP
|
||||
|
||||
#define SRND SI // SRND is same register as CTX
|
||||
|
||||
#define T1 R12
|
||||
|
||||
#define y0 R13
|
||||
#define y1 R14
|
||||
#define y2 R15
|
||||
#define y3 DI
|
||||
|
||||
// Offsets
|
||||
#define XFER_SIZE 2*2*68*4
|
||||
#define INP_END_SIZE 8
|
||||
#define INP_SIZE 8
|
||||
|
||||
#define _XFER 0
|
||||
#define _INP_END _XFER + XFER_SIZE
|
||||
#define _INP _INP_END + INP_END_SIZE
|
||||
#define STACK_SIZE _INP + INP_SIZE
|
||||
|
||||
|
||||
// update XDWORD0
|
||||
#define SM3_SCHED(XDWORD0, XDWORD1, XDWORD2, XDWORD3)\
|
||||
; \ // ################################### Message Schedule ###########################
|
||||
VPALIGNR $8, XDWORD2, XDWORD3, XTMP0; \ // XTMP0 = W[-6]
|
||||
VPALIGNR $12, XDWORD0, XDWORD1, XTMP1; \ // XTMP1 = W[-13]
|
||||
VPSLLD $7, XTMP1, XTMP2; \
|
||||
VPSRLD $(32-7), XTMP1, XTMP1; \
|
||||
VPXOR XTMP2, XTMP1, XTMP1; \ // XTMP1 = (w[-13] <<< 7)
|
||||
VPXOR XTMP1, XTMP0, XTMP0; \ // XTMP0 = (w[-13] <<< 7) ^ w[-6]
|
||||
; \
|
||||
VPALIGNR $12, XDWORD1, XDWORD2, XTMP1; \ // XTMP1 = W[-9]
|
||||
VPXOR XDWORD0, XTMP1, XTMP1; \ // XTMP1 = W[-9]^W[-16]
|
||||
; \
|
||||
VPSHUFD $0xA5, XDWORD3, XTMP2; \ // XTMP2 = W[-3] {BBAA}
|
||||
VPSRLQ $17, XTMP2, XTMP4; \ // XTMP4 = W[-3] <<< 15 {xBxA}
|
||||
VPSHUFB shuff_00BA<>(SB), XTMP4, XTMP4; \ // XTMP4 = W[-3] <<< 15 {00BA}
|
||||
VPXOR XTMP1, XTMP4, XTMP4; \ // XTMP4 = W[-9]^W[-16] ^ (W[-3] <<< 15) {xxBA}
|
||||
VPSHUFD $0x50, XTMP4, XTMP4; \ // XTMP4 = W[-9]^W[-16] ^ (W[-3] <<< 15) {BBAA}
|
||||
VPSRLQ $17, XTMP4,XTMP2; \ // {xBxA}
|
||||
VPSRLQ $9, XTMP4,XTMP3; \ // {xBxA}
|
||||
VPXOR XTMP2, XTMP4, XTMP4; \ //
|
||||
VPXOR XTMP3, XTMP4, XTMP4; \ // XTMP4 = p1 {xBxA}
|
||||
VPSHUFB shuff_00BA<>(SB), XTMP4, XTMP4; \ // XTMP4 = p1 {00BA}
|
||||
VPXOR XTMP4, XTMP0, XTMP5; \ // XTMP5 = {..., ..., W[1], W[0]}
|
||||
; \
|
||||
VPALIGNR $4, XDWORD3, XTMP5, XTMP2; \ // XTMP2 = {W[0], W[-1], W[-2], W[-3]}
|
||||
VPSHUFD $0xFA, XTMP2, XTMP2; \ // XTMP2 = {W[0], W[0], W[-1], W[-1]} {DDCC}
|
||||
VPSRLQ $17, XTMP2, XTMP4; \ // XTMP4 = W[-3] <<< 15 {xDxC}
|
||||
VPSHUFB shuff_DC00<>(SB), XTMP4, XTMP4; \ // XTMP4 = W[-3] <<< 15 {DC00}
|
||||
VPXOR XTMP1, XTMP4, XTMP4; \ // XTMP4 = W[-9]^W[-16] ^ (W[-3] <<< 15) {DCxx}
|
||||
VPSHUFD $0xFA, XTMP4, XTMP4; \ // XTMP4 = W[-9]^W[-16] ^ (W[-3] <<< 15) {DDCC}
|
||||
VPSRLQ $17, XTMP4,XTMP2; \
|
||||
VPSRLQ $9, XTMP4,XTMP3; \
|
||||
VPXOR XTMP2, XTMP4, XTMP4; \
|
||||
VPXOR XTMP3, XTMP4, XTMP4; \ // XTMP4 = p1 {xDxC}
|
||||
VPSHUFB shuff_DC00<>(SB), XTMP4, XTMP4; \ // XTMP4 = p1 {DC00}
|
||||
VPXOR XTMP4, XTMP5,XDWORD0
|
||||
|
||||
|
||||
// 前16轮计算-0
|
||||
// SRND = # of {4 round}
|
||||
// T is saved in (dist_T)(TBL)(SRND*1)
|
||||
// W is saved in (dist_W)(SP)(SRND*2)
|
||||
// W' is saved in (dist_W + 68*4*2)(SP)(SRND*1)
|
||||
#define DO_ROUND16(dist_T, dist_W, a, b, c, d, e, f, g, h) \
|
||||
; \ // ################################### RND 0 - 15 ###########################
|
||||
RORXL $(32-12), a, y2; \ // y2 = a <<< 12
|
||||
MOVL y2, y3; \
|
||||
ADDL e, y3; \ // y3 = (a <<< 12) + e
|
||||
ADDL (dist_T)(TBL)(SRND*1), y3; \ // y3 = (a <<< 12) + e + T
|
||||
RORXL $(32-7), y3, y3; \ // y3 = ss1
|
||||
ADDL y3, h; \ // h = h+ss1
|
||||
XORL y2, y3; \ // y3 = ss2
|
||||
ADDL y3, d; \ // d = d+ss2
|
||||
; \
|
||||
ADDL (dist_W)(SP)(SRND*2), h; \ // h = h + ss1 + w
|
||||
ADDL (dist_W+68*4*2)(SP)(SRND*2), d; \ // d = d + ss2 + w'
|
||||
; \
|
||||
MOVL a, y1; \ // y1 = a //FF //PARITY
|
||||
XORL b, y1; \ // y1 = a^b //FF //PARITY
|
||||
XORL c, y1; \ // y1 = a^b^c //FF //PARITY
|
||||
ADDL y1, d; \ // d = TT1
|
||||
; \
|
||||
MOVL e, y2; \ // y2 = e // GG //PARITY
|
||||
XORL f, y2; \ // y2 = e^f // GG //PARITY
|
||||
XORL g, y2; \ // y2 = e^f^g // GG //PARITY
|
||||
ADDL y2, h; \ // h = TT2
|
||||
; \
|
||||
RORXL $(32-8), h, y0; \ // y0 = TT2<<<8
|
||||
XORL h,y0; \ // y0 = (TT2<<<8)^TT2
|
||||
RORXL $(32-9), y0, y0; \ // y0 = ((TT2<<<8)^TT2)<<<9
|
||||
XORL y0, h; \ // h = p0(TT2)
|
||||
; \
|
||||
RORXL $(32-9), b, b; \
|
||||
RORXL $(32-19), f, f
|
||||
|
||||
// 后48轮计算
|
||||
#define DO_ROUND48(dist_T, dist_W, a, b, c, d, e, f, g, h) \
|
||||
; \ // ################################### RND 16 - 63 ###########################
|
||||
RORXL $(32-12), a, y2; \ // y2 = a <<< 12
|
||||
MOVL y2, y3; \
|
||||
ADDL e, y3; \ // y3 = (a <<< 12) + e
|
||||
ADDL (dist_T)(TBL)(SRND*1), y3; \ // y3 = (a <<< 12) + e + T
|
||||
RORXL $(32-7), y3, y3; \ // y3 = ss1
|
||||
ADDL y3, h; \ // h = h+ss1
|
||||
XORL y2, y3; \ // y3 = ss2
|
||||
ADDL y3, d; \ // d = d+ss2
|
||||
; \
|
||||
ADDL (dist_W)(SP)(SRND*2), h; \ // h = h + ss1 + w
|
||||
ADDL (dist_W+68*4*2)(SP)(SRND*2), d; \ // d = d + ss2 + w'
|
||||
; \
|
||||
MOVL a, y3; \ // y3 = a //FF MAJA
|
||||
ORL c, y3; \ // y3 = a|c // MAJA
|
||||
ANDL b, y3; \ // y3 = (a|c)&b // MAJA
|
||||
MOVL a, T1; \ // T1 = a // MAJB
|
||||
ANDL c, T1; \ // T1 = a&c // MAJB
|
||||
ORL T1, y3; \ // y3 = MAJ = ((a|c)&b)|(a&c) // MAJ
|
||||
ADDL y3, d; \ // d = TT1
|
||||
; \
|
||||
MOVL f, y2; \ // y2 = f //GG CH
|
||||
XORL g, y2; \ // y2 = f^g // CH
|
||||
ANDL e, y2; \ // y2 = (f^g)&e // CH
|
||||
XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
|
||||
ADDL y2, h; \ // h = TT2
|
||||
; \
|
||||
RORXL $(32-8), h, y0; \ // y0 = TT2<<<8
|
||||
XORL h,y0; \ // y0 = (TT2<<<8)^TT2
|
||||
RORXL $(32-9), y0, y0; \ // y0 = ((TT2<<<8)^TT2)<<<9
|
||||
XORL y0, h; \ // h = p0(TT2)
|
||||
; \
|
||||
RORXL $(32-9), b, b; \
|
||||
RORXL $(32-19), f, f
|
||||
|
||||
|
||||
// stack:
|
||||
// block0 block1
|
||||
// 0*8: W[0:4] V[0:4]
|
||||
// 1*8: W[4:8] V[4:8]
|
||||
// ...
|
||||
// 67*8: W[64:68] V[64:68]
|
||||
// 68*8: W'[0:4] V'[0:4]
|
||||
// 69*8: W'[4:8] V'[4:8]
|
||||
// ...
|
||||
// 135*8: W'[64:68] V'[64:68]
|
||||
// 136*8: _INP_END(SP) - Pointer to the last block
|
||||
// 137*8: _INP(SP) - Save INP in round computation.
|
||||
//
|
||||
// STACK_SIZE = 1088+8+8 = 1104
|
||||
// func blockAsmAVX2(dig *digest, p []byte)
|
||||
TEXT ·blockAsmAVX2(SB), 0, $1104-32
|
||||
MOVQ dig+0(FP), CTX
|
||||
MOVQ p_base+8(FP), INP
|
||||
MOVQ p_len+16(FP), NUM_BYTES
|
||||
|
||||
LEAQ -64(INP)(NUM_BYTES*1), NUM_BYTES // Pointer to the last block
|
||||
MOVQ NUM_BYTES, _INP_END(SP) // save to stack
|
||||
|
||||
CMPQ NUM_BYTES, INP
|
||||
JE avx2_only_one_block
|
||||
|
||||
// Load initial digest
|
||||
MOVL 0(CTX), a // a = H0
|
||||
MOVL 4(CTX), b // b = H1
|
||||
MOVL 8(CTX), c // c = H2
|
||||
MOVL 12(CTX), d // d = H3
|
||||
MOVL 16(CTX), e // e = H4
|
||||
MOVL 20(CTX), f // f = H5
|
||||
MOVL 24(CTX), g // g = H6
|
||||
MOVL 28(CTX), h // h = H7
|
||||
|
||||
avx2_loop0: // at each iteration works with one block (512 bit)
|
||||
|
||||
// load two blocks,64*2 bytes
|
||||
VMOVDQU (0*32)(INP), XTMP0 // p[0:4]
|
||||
VMOVDQU (1*32)(INP), XTMP1
|
||||
VMOVDQU (2*32)(INP), XTMP2
|
||||
VMOVDQU (3*32)(INP), XTMP3
|
||||
|
||||
VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
|
||||
|
||||
// Apply Byte Flip Mask: LE -> BE
|
||||
VPSHUFB BYTE_FLIP_MASK, XTMP0, XTMP0
|
||||
VPSHUFB BYTE_FLIP_MASK, XTMP1, XTMP1
|
||||
VPSHUFB BYTE_FLIP_MASK, XTMP2, XTMP2
|
||||
VPSHUFB BYTE_FLIP_MASK, XTMP3, XTMP3
|
||||
|
||||
// XTMP0:XTMP1 - first block
|
||||
// XTMP0: w7, w6, w5, w4, w3, w2, w1,w0
|
||||
// XTMP1: w15,w14,w13,w12,w11,w10,w9,w8
|
||||
// XTMP3:XTMP2 - second block
|
||||
// XTMP2: u7, u6, u5, u4, u3, u2, u1,u0
|
||||
// XTMP3: u15,u14,u13,u12,u11,u10,u9,u8
|
||||
|
||||
// XDWORD0: u3, u2, u1, u0, w3, w2, w1,w0
|
||||
// XDWORD1: u7, u6, u5, u4, w7, w6, w5, w4
|
||||
// XDWORD2: u11,u10,u9, u8, w11,w10,w9,w8
|
||||
// XDWORD3: u15,u14,u13,u12,w15,w14,w13,w12
|
||||
|
||||
// Transpose data into high/low parts
|
||||
VPERM2I128 $0x20, XTMP2, XTMP0, XDWORD0 // w3, w2, w1, w0
|
||||
VPERM2I128 $0x31, XTMP2, XTMP0, XDWORD1 // w7, w6, w5, w4
|
||||
VPERM2I128 $0x20, XTMP3, XTMP1, XDWORD2 // w11, w10, w9, w8
|
||||
VPERM2I128 $0x31, XTMP3, XTMP1, XDWORD3 // w15, w14, w13, w12
|
||||
MOVQ $T256<>(SB), TBL // Loading address of table with round-specific constants
|
||||
|
||||
avx2_last_block_enter:
|
||||
ADDQ $64, INP
|
||||
MOVQ INP, _INP(SP)
|
||||
XORQ SRND, SRND // SRND increace 16 of each 4 rounds (dist of T)
|
||||
|
||||
// for w0 - w15
|
||||
// Do 4 rounds and scheduling
|
||||
VMOVDQU XDWORD0, (_XFER + 0*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD0, XDWORD1, XFER
|
||||
VMOVDQU XFER, (_XFER + 0*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD0, XDWORD1, XDWORD2, XDWORD3)
|
||||
DO_ROUND16(0*4, 0*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND16(1*4, 0*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND16(2*4, 0*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND16(3*4, 0*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD1, (_XFER + 1*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD1, XDWORD2, XFER
|
||||
VMOVDQU XFER, (_XFER + 1*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD1, XDWORD2, XDWORD3, XDWORD0)
|
||||
DO_ROUND16(4*4, 1*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND16(5*4, 1*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND16(6*4, 1*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND16(7*4, 1*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD2, (_XFER + 2*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD2, XDWORD3, XFER
|
||||
VMOVDQU XFER, (_XFER + 2*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD2, XDWORD3, XDWORD0, XDWORD1)
|
||||
DO_ROUND16(8*4, 2*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND16(9*4, 2*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND16(10*4,2*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND16(11*4,2*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD3, (_XFER + 3*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD3, XDWORD0, XFER
|
||||
VMOVDQU XFER, (_XFER + 3*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD3, XDWORD0, XDWORD1, XDWORD2)
|
||||
DO_ROUND16(12*4, 3*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND16(13*4, 3*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND16(14*4, 3*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND16(15*4, 3*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
ADDQ $4*16, SRND
|
||||
|
||||
avx2_loop1:
|
||||
// for w16 - w47 with scheduling (32 rounds)
|
||||
VMOVDQU XDWORD0, (_XFER + 0*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD0, XDWORD1, XFER
|
||||
VMOVDQU XFER, (_XFER + 0*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD0, XDWORD1, XDWORD2, XDWORD3)
|
||||
DO_ROUND48(0*4, 0*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(1*4, 0*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(2*4, 0*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(3*4, 0*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD1, (_XFER + 1*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD1, XDWORD2, XFER
|
||||
VMOVDQU XFER, (_XFER + 1*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD1, XDWORD2, XDWORD3, XDWORD0)
|
||||
DO_ROUND48(4*4, 1*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(5*4, 1*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(6*4, 1*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(7*4, 1*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD2, (_XFER + 2*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD2, XDWORD3, XFER
|
||||
VMOVDQU XFER, (_XFER + 2*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD2, XDWORD3, XDWORD0, XDWORD1)
|
||||
DO_ROUND48(8*4, 2*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(9*4, 2*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(10*4,2*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(11*4,2*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD3, (_XFER + 3*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD3, XDWORD0, XFER
|
||||
VMOVDQU XFER, (_XFER + 3*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD3, XDWORD0, XDWORD1, XDWORD2)
|
||||
DO_ROUND48(12*4,3*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(13*4,3*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(14*4,3*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(15*4,3*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
ADDQ $4*16, SRND
|
||||
CMPQ SRND, $12*16
|
||||
JB avx2_loop1
|
||||
|
||||
// w48 - w63 processed with one scheduling (last 16 rounds)
|
||||
VMOVDQU XDWORD0, (_XFER + 0*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD0, XDWORD1, XFER
|
||||
VMOVDQU XFER, (_XFER + 0*32+68*4*2)(SP)(SRND*2)
|
||||
SM3_SCHED(XDWORD0, XDWORD1, XDWORD2, XDWORD3) // scheduling XDWORD0 for W64-W67
|
||||
DO_ROUND48(0*4, 0*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(1*4, 0*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(2*4, 0*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(3*4, 0*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD1, (_XFER + 1*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD1, XDWORD2, XFER
|
||||
VMOVDQU XFER, (_XFER + 1*32+68*4*2)(SP)(SRND*2)
|
||||
DO_ROUND48(4*4, 1*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(5*4, 1*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(6*4, 1*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(7*4, 1*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD2, (_XFER + 2*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD2, XDWORD3, XFER
|
||||
VMOVDQU XFER, (_XFER + 2*32+68*4*2)(SP)(SRND*2)
|
||||
DO_ROUND48(8*4, 2*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(9*4, 2*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(10*4,2*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(11*4,2*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
VMOVDQU XDWORD3, (_XFER + 3*32)(SP)(SRND*2)
|
||||
VPXOR XDWORD3, XDWORD0, XFER
|
||||
VMOVDQU XFER, (_XFER + 3*32+68*4*2)(SP)(SRND*2)
|
||||
DO_ROUND48(12*4, 3*32+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(13*4, 3*32+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(14*4, 3*32+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(15*4, 3*32+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
MOVQ dig+0(FP), CTX // d.h[8]
|
||||
MOVQ _INP(SP), INP
|
||||
|
||||
xorm( 0(CTX), a)
|
||||
xorm( 4(CTX), b)
|
||||
xorm( 8(CTX), c)
|
||||
xorm( 12(CTX), d)
|
||||
xorm( 16(CTX), e)
|
||||
xorm( 20(CTX), f)
|
||||
xorm( 24(CTX), g)
|
||||
xorm( 28(CTX), h)
|
||||
|
||||
CMPQ _INP_END(SP), INP
|
||||
JB done_hash
|
||||
|
||||
XORQ SRND, SRND
|
||||
|
||||
avx2_loop3: // Do second block using previously scheduled results
|
||||
DO_ROUND16(0, 16+0, a, b, c, d, e, f, g, h)
|
||||
DO_ROUND16(4, 16+4, d, a, b, c, h, e, f, g)
|
||||
DO_ROUND16(8, 16+8, c, d, a, b, g, h, e, f)
|
||||
DO_ROUND16(12, 16+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
ADDQ $16, SRND
|
||||
CMPQ SRND, $4*16
|
||||
JB avx2_loop3
|
||||
avx2_loop4:
|
||||
DO_ROUND48(0, 16+0,a, b, c, d, e, f, g, h)
|
||||
DO_ROUND48(4, 16+4,d, a, b, c, h, e, f, g)
|
||||
DO_ROUND48(8, 16+8,c, d, a, b, g, h, e, f)
|
||||
DO_ROUND48(12, 16+12, b, c, d, a, f, g, h, e)
|
||||
|
||||
ADDQ $16, SRND
|
||||
CMPQ SRND, $16*16
|
||||
JB avx2_loop4
|
||||
|
||||
MOVQ dig+0(FP), CTX // d.h[8]
|
||||
MOVQ _INP(SP), INP
|
||||
ADDQ $64, INP
|
||||
|
||||
xorm( 0(CTX), a)
|
||||
xorm( 4(CTX), b)
|
||||
xorm( 8(CTX), c)
|
||||
xorm( 12(CTX), d)
|
||||
xorm( 16(CTX), e)
|
||||
xorm( 20(CTX), f)
|
||||
xorm( 24(CTX), g)
|
||||
xorm( 28(CTX), h)
|
||||
|
||||
CMPQ _INP_END(SP), INP
|
||||
JA avx2_loop0
|
||||
JB done_hash
|
||||
|
||||
avx2_do_last_block:
|
||||
|
||||
VMOVDQU 0(INP), XWORD0
|
||||
VMOVDQU 16(INP), XWORD1
|
||||
VMOVDQU 32(INP), XWORD2
|
||||
VMOVDQU 48(INP), XWORD3
|
||||
|
||||
VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
|
||||
|
||||
VPSHUFB X_BYTE_FLIP_MASK, XWORD0, XWORD0
|
||||
VPSHUFB X_BYTE_FLIP_MASK, XWORD1, XWORD1
|
||||
VPSHUFB X_BYTE_FLIP_MASK, XWORD2, XWORD2
|
||||
VPSHUFB X_BYTE_FLIP_MASK, XWORD3, XWORD3
|
||||
MOVQ $T256<>(SB), TBL
|
||||
|
||||
JMP avx2_last_block_enter
|
||||
|
||||
avx2_only_one_block:
|
||||
// Load initial digest
|
||||
MOVL 0(CTX), a // a = H0
|
||||
MOVL 4(CTX), b // b = H1
|
||||
MOVL 8(CTX), c // c = H2
|
||||
MOVL 12(CTX), d // d = H3
|
||||
MOVL 16(CTX), e // e = H4
|
||||
MOVL 20(CTX), f // f = H5
|
||||
MOVL 24(CTX), g // g = H6
|
||||
MOVL 28(CTX), h // h = H7
|
||||
|
||||
JMP avx2_do_last_block
|
||||
|
||||
done_hash:
|
||||
VZEROUPPER
|
||||
RET
|
||||
|
||||
// shuffle byte order from LE to BE
|
||||
DATA flip_mask<>+0x00(SB)/8, $0x0405060700010203
|
||||
DATA flip_mask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
|
||||
DATA flip_mask<>+0x10(SB)/8, $0x0405060700010203
|
||||
DATA flip_mask<>+0x18(SB)/8, $0x0c0d0e0f08090a0b
|
||||
GLOBL flip_mask<>(SB), 8, $32
|
||||
|
||||
// shuffle xBxA -> 00BA
|
||||
DATA shuff_00BA<>+0x00(SB)/8, $0x0b0a090803020100
|
||||
DATA shuff_00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shuff_00BA<>+0x10(SB)/8, $0x0b0a090803020100
|
||||
DATA shuff_00BA<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
GLOBL shuff_00BA<>(SB), 8, $32
|
||||
|
||||
// shuffle xDxC -> DC00
|
||||
DATA shuff_DC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shuff_DC00<>+0x08(SB)/8, $0x0b0a090803020100
|
||||
DATA shuff_DC00<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shuff_DC00<>+0x18(SB)/8, $0x0b0a090803020100
|
||||
GLOBL shuff_DC00<>(SB), 8, $32
|
||||
|
||||
// rotate of Tj: rotT[i] = Tj << (j mod 32)
|
||||
DATA T256<>+0x0(SB)/4, $0x79cc4519
|
||||
DATA T256<>+0x4(SB)/4, $0xf3988a32
|
||||
DATA T256<>+0x8(SB)/4, $0xe7311465
|
||||
DATA T256<>+0xc(SB)/4, $0xce6228cb
|
||||
DATA T256<>+0x10(SB)/4, $0x9cc45197
|
||||
DATA T256<>+0x14(SB)/4, $0x3988a32f
|
||||
DATA T256<>+0x18(SB)/4, $0x7311465e
|
||||
DATA T256<>+0x1c(SB)/4, $0xe6228cbc
|
||||
DATA T256<>+0x20(SB)/4, $0xcc451979
|
||||
DATA T256<>+0x24(SB)/4, $0x988a32f3
|
||||
DATA T256<>+0x28(SB)/4, $0x311465e7
|
||||
DATA T256<>+0x2c(SB)/4, $0x6228cbce
|
||||
DATA T256<>+0x30(SB)/4, $0xc451979c
|
||||
DATA T256<>+0x34(SB)/4, $0x88a32f39
|
||||
DATA T256<>+0x38(SB)/4, $0x11465e73
|
||||
DATA T256<>+0x3c(SB)/4, $0x228cbce6
|
||||
DATA T256<>+0x40(SB)/4, $0x9d8a7a87
|
||||
DATA T256<>+0x44(SB)/4, $0x3b14f50f
|
||||
DATA T256<>+0x48(SB)/4, $0x7629ea1e
|
||||
DATA T256<>+0x4c(SB)/4, $0xec53d43c
|
||||
DATA T256<>+0x50(SB)/4, $0xd8a7a879
|
||||
DATA T256<>+0x54(SB)/4, $0xb14f50f3
|
||||
DATA T256<>+0x58(SB)/4, $0x629ea1e7
|
||||
DATA T256<>+0x5c(SB)/4, $0xc53d43ce
|
||||
DATA T256<>+0x60(SB)/4, $0x8a7a879d
|
||||
DATA T256<>+0x64(SB)/4, $0x14f50f3b
|
||||
DATA T256<>+0x68(SB)/4, $0x29ea1e76
|
||||
DATA T256<>+0x6c(SB)/4, $0x53d43cec
|
||||
DATA T256<>+0x70(SB)/4, $0xa7a879d8
|
||||
DATA T256<>+0x74(SB)/4, $0x4f50f3b1
|
||||
DATA T256<>+0x78(SB)/4, $0x9ea1e762
|
||||
DATA T256<>+0x7c(SB)/4, $0x3d43cec5
|
||||
DATA T256<>+0x80(SB)/4, $0x7a879d8a
|
||||
DATA T256<>+0x84(SB)/4, $0xf50f3b14
|
||||
DATA T256<>+0x88(SB)/4, $0xea1e7629
|
||||
DATA T256<>+0x8c(SB)/4, $0xd43cec53
|
||||
DATA T256<>+0x90(SB)/4, $0xa879d8a7
|
||||
DATA T256<>+0x94(SB)/4, $0x50f3b14f
|
||||
DATA T256<>+0x98(SB)/4, $0xa1e7629e
|
||||
DATA T256<>+0x9c(SB)/4, $0x43cec53d
|
||||
DATA T256<>+0xa0(SB)/4, $0x879d8a7a
|
||||
DATA T256<>+0xa4(SB)/4, $0x0f3b14f5
|
||||
DATA T256<>+0xa8(SB)/4, $0x1e7629ea
|
||||
DATA T256<>+0xac(SB)/4, $0x3cec53d4
|
||||
DATA T256<>+0xb0(SB)/4, $0x79d8a7a8
|
||||
DATA T256<>+0xb4(SB)/4, $0xf3b14f50
|
||||
DATA T256<>+0xb8(SB)/4, $0xe7629ea1
|
||||
DATA T256<>+0xbc(SB)/4, $0xcec53d43
|
||||
DATA T256<>+0xc0(SB)/4, $0x9d8a7a87
|
||||
DATA T256<>+0xc4(SB)/4, $0x3b14f50f
|
||||
DATA T256<>+0xc8(SB)/4, $0x7629ea1e
|
||||
DATA T256<>+0xcc(SB)/4, $0xec53d43c
|
||||
DATA T256<>+0xd0(SB)/4, $0xd8a7a879
|
||||
DATA T256<>+0xd4(SB)/4, $0xb14f50f3
|
||||
DATA T256<>+0xd8(SB)/4, $0x629ea1e7
|
||||
DATA T256<>+0xdc(SB)/4, $0xc53d43ce
|
||||
DATA T256<>+0xe0(SB)/4, $0x8a7a879d
|
||||
DATA T256<>+0xe4(SB)/4, $0x14f50f3b
|
||||
DATA T256<>+0xe8(SB)/4, $0x29ea1e76
|
||||
DATA T256<>+0xec(SB)/4, $0x53d43cec
|
||||
DATA T256<>+0xf0(SB)/4, $0xa7a879d8
|
||||
DATA T256<>+0xf4(SB)/4, $0x4f50f3b1
|
||||
DATA T256<>+0xf8(SB)/4, $0x9ea1e762
|
||||
DATA T256<>+0xfc(SB)/4, $0x3d43cec5
|
||||
GLOBL T256<>(SB), (NOPTR + RODATA), $256
|
||||
@@ -0,0 +1,6 @@
|
||||
//go:build !amd64
|
||||
// +build !amd64
|
||||
|
||||
package sm3
|
||||
|
||||
var block = blockGeneric
|
||||
@@ -0,0 +1,88 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package sm3
|
||||
|
||||
// block 未优化的参考实现
|
||||
|
||||
// t[i] = Tj << (j mod 32)
|
||||
var t = [64]uint32{
|
||||
0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb, 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
|
||||
0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce, 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
|
||||
0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
|
||||
0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
|
||||
0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53, 0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
|
||||
0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4, 0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
|
||||
0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
|
||||
0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
|
||||
}
|
||||
|
||||
// Block functions the standerd algo, for compare test
|
||||
func blockRef(dig *digest, p []byte) {
|
||||
var a, b, c, d, e, f, g, h uint32
|
||||
var w [16]uint32
|
||||
|
||||
for len(p) >= chunk {
|
||||
a = dig.h[0]
|
||||
b = dig.h[1]
|
||||
c = dig.h[2]
|
||||
d = dig.h[3]
|
||||
e = dig.h[4]
|
||||
f = dig.h[5]
|
||||
g = dig.h[6]
|
||||
h = dig.h[7]
|
||||
for i := 0; i < 16; i++ {
|
||||
j := i * 4
|
||||
w[i] = uint32(p[j+3]) | uint32(p[j+2])<<8 | uint32(p[j+1])<<16 | uint32(p[j])<<24
|
||||
}
|
||||
|
||||
for i := 0; i < 16; i++ {
|
||||
x := (a<<12 | a>>20)
|
||||
ss1 := x + e + t[i]
|
||||
ss1 = ss1<<7 | ss1>>25
|
||||
ss2 := ss1 ^ x
|
||||
tt1 := (a ^ b ^ c) + d + ss2 + (w[i] ^ w[(i+4)&15])
|
||||
tt2 := (e ^ f ^ g) + h + ss1 + w[i]
|
||||
d = c
|
||||
c = b<<9 | b>>23
|
||||
b = a
|
||||
a = tt1
|
||||
h = g
|
||||
g = f<<19 | f>>13
|
||||
f = e
|
||||
e = tt2 ^ (tt2<<9 | tt2>>23) ^ (tt2<<17 | tt2>>15)
|
||||
tw := w[i] ^ w[(i+7)&15] ^ (w[(i+13)&15]<<15 | w[(i+13)&15]>>17)
|
||||
w[i] = tw ^ (tw<<15 | tw>>17) ^ (tw<<23 | tw>>9) ^ (w[(i+3)&15]<<7 | w[(i+3)&15]>>25) ^ w[(i+10)&15]
|
||||
}
|
||||
|
||||
for i := 16; i < 64; i++ {
|
||||
x := (a<<12 | a>>20)
|
||||
ss1 := x + e + t[i]
|
||||
ss1 = ss1<<7 | ss1>>25
|
||||
ss2 := ss1 ^ x
|
||||
tt1 := ((a & b) | (b & c) | (a & c)) + d + ss2 + (w[i&15] ^ w[(i+4)&15])
|
||||
tt2 := ((e & f) | (^e & g)) + h + ss1 + w[i&15]
|
||||
d = c
|
||||
c = b<<9 | b>>23
|
||||
b = a
|
||||
a = tt1
|
||||
h = g
|
||||
g = f<<19 | f>>13
|
||||
f = e
|
||||
e = tt2 ^ (tt2<<9 | tt2>>23) ^ (tt2<<17 | tt2>>15)
|
||||
tw := w[i&15] ^ w[(i+7)&15] ^ (w[(i+13)&15]<<15 | w[(i+13)&15]>>17)
|
||||
w[i&15] = tw ^ (tw<<15 | tw>>17) ^ (tw<<23 | tw>>9) ^ (w[(i+3)&15]<<7 | w[(i+3)&15]>>25) ^ w[(i+10)&15]
|
||||
}
|
||||
|
||||
p = p[chunk:]
|
||||
dig.h[0] ^= a
|
||||
dig.h[1] ^= b
|
||||
dig.h[2] ^= c
|
||||
dig.h[3] ^= d
|
||||
dig.h[4] ^= e
|
||||
dig.h[5] ^= f
|
||||
dig.h[6] ^= g
|
||||
dig.h[7] ^= h
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package sm3
|
||||
|
||||
import (
|
||||
"xdx.jelly/xgcl/gerrors"
|
||||
)
|
||||
|
||||
//go:generate stringer -type=ErrorCode -linecomment -output=errors_string.go errors.go
|
||||
type ErrorCode gerrors.ErrorCode
|
||||
|
||||
func (e ErrorCode) Error() string {
|
||||
return gerrors.Format(uint32(e), e.String())
|
||||
}
|
||||
|
||||
// error codes
|
||||
const (
|
||||
ErrInvalidInput ErrorCode = 0x01003000 + iota //输入不合法
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// Code generated by "stringer -type=ErrorCode -linecomment -output=errors_string.go errors.go"; DO NOT EDIT.
|
||||
|
||||
package sm3
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[ErrInvalidInput-16789504]
|
||||
}
|
||||
|
||||
const _ErrorCode_name = "输入不合法"
|
||||
|
||||
var _ErrorCode_index = [...]uint8{0, 15}
|
||||
|
||||
func (i ErrorCode) String() string {
|
||||
i -= 16789504
|
||||
if i >= ErrorCode(len(_ErrorCode_index)-1) {
|
||||
return "ErrorCode(" + strconv.FormatInt(int64(i+16789504), 10) + ")"
|
||||
}
|
||||
return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package sm3
|
||||
|
||||
import "hash"
|
||||
|
||||
// NewSm2Precomputed return a Hash which is the internal states after
|
||||
// d.Write(entl[:])
|
||||
// d.Write(id)
|
||||
// d.Write(abg)
|
||||
func NewSm2Precomputed() hash.Hash {
|
||||
return &digest{
|
||||
h: [8]uint32{
|
||||
0xadadedb5, 0x0446043f,
|
||||
0x08a87ace, 0xe86d2243,
|
||||
0x8e232383, 0xbfc81fe2,
|
||||
0xcf9117c8, 0x4707011d,
|
||||
},
|
||||
x: [64]byte{
|
||||
0x21, 0x53, 0xd0, 0xa9,
|
||||
0x87, 0x7c, 0xc6, 0x2a,
|
||||
0x47, 0x40, 0x02, 0xdf,
|
||||
0x32, 0xe5, 0x21, 0x39,
|
||||
0xf0, 0xa0,
|
||||
},
|
||||
nx: 18,
|
||||
len: 146,
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
Package sm3 implements the SM3 Hash algorithms
|
||||
*/
|
||||
package sm3
|
||||
|
||||
import (
|
||||
"hash"
|
||||
|
||||
"xdx.jelly/xgcl/sm"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 注册sm.SM3、sm.SM3WithID到sm.hashs中去.
|
||||
sm.RegisterHash(sm.SM3, New)
|
||||
sm.RegisterHash(sm.SM3WithID, New)
|
||||
}
|
||||
|
||||
type digest struct {
|
||||
h [8]uint32
|
||||
x [chunk]byte
|
||||
nx int
|
||||
len uint64
|
||||
}
|
||||
|
||||
// NewDigest return a new digest type, void change `digest` to `Digest`.
|
||||
// 相比标准库,增加此函数。
|
||||
// 在上下文明确使用sm3的时候,可以显示用这个函数来获取sm3的digest实例,
|
||||
// 而不是通过New()得到Hash接口。
|
||||
func NewDigest() *digest {
|
||||
d := new(digest)
|
||||
d.Reset()
|
||||
return d
|
||||
}
|
||||
|
||||
// New returns a new hash.Hash computing the SM3 checksum. The Hash also
|
||||
// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
|
||||
// marshal and unmarshal the internal state of the hash.
|
||||
func New() hash.Hash {
|
||||
return NewDigest()
|
||||
}
|
||||
|
||||
// Reset reset the states
|
||||
func (d *digest) Reset() {
|
||||
d.h[0] = init0
|
||||
d.h[1] = init1
|
||||
d.h[2] = init2
|
||||
d.h[3] = init3
|
||||
d.h[4] = init4
|
||||
d.h[5] = init5
|
||||
d.h[6] = init6
|
||||
d.h[7] = init7
|
||||
d.nx = 0
|
||||
d.len = 0
|
||||
}
|
||||
|
||||
/*
|
||||
MarshalBinary和UnmarshalBinary实现了encoding.BinaryMarshaler和
|
||||
encoding.BinaryMarshaler接口,可以对Sm3的中间状态转化为byte序列存储。
|
||||
比如kdf函数要计算SM3(z||cnt), cnt = 1,2,3,4...,可以先update(z),保存此时
|
||||
状态。
|
||||
|
||||
用法:
|
||||
dig := New()
|
||||
io.WriteString(dig, "a")
|
||||
// New 返回的是hash接口, 转换为BinaryMarshaler接口
|
||||
state, _ := dig.(encoding.BinaryMarshaler).MarshalBinary()
|
||||
// dig do something
|
||||
dig.(encoding.BinaryUnmarshaler).UnmarshalBinary(state)
|
||||
|
||||
补充:我们增加了NewDigest(), 返回*digest,因此可以直接用赋值保存。
|
||||
d1 := NewDigest()
|
||||
// ...
|
||||
*d2 := *d1
|
||||
*/
|
||||
|
||||
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
||||
// marshal a digest to []byte to save
|
||||
// no error return.
|
||||
func (d *digest) MarshalBinary() ([]byte, error) {
|
||||
b := make([]byte, 0, marshaledSize)
|
||||
b = append(b, magic...)
|
||||
b = appendUint32(b, d.h[0])
|
||||
b = appendUint32(b, d.h[1])
|
||||
b = appendUint32(b, d.h[2])
|
||||
b = appendUint32(b, d.h[3])
|
||||
b = appendUint32(b, d.h[4])
|
||||
b = appendUint32(b, d.h[5])
|
||||
b = appendUint32(b, d.h[6])
|
||||
b = appendUint32(b, d.h[7])
|
||||
b = append(b, d.x[:]...)
|
||||
b = appendUint64(b, d.len)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements the encoding.BinaryMarshaler interface
|
||||
// recover a digest from []byte
|
||||
func (d *digest) UnmarshalBinary(b []byte) error {
|
||||
if len(b) < marshaledSize || string(b[:len(magic)]) != magic {
|
||||
return ErrInvalidInput
|
||||
}
|
||||
|
||||
b = b[len(magic):]
|
||||
b, d.h[0] = consumeUint32(b)
|
||||
b, d.h[1] = consumeUint32(b)
|
||||
b, d.h[2] = consumeUint32(b)
|
||||
b, d.h[3] = consumeUint32(b)
|
||||
b, d.h[4] = consumeUint32(b)
|
||||
b, d.h[5] = consumeUint32(b)
|
||||
b, d.h[6] = consumeUint32(b)
|
||||
b, d.h[7] = consumeUint32(b)
|
||||
b = b[copy(d.x[:], b):]
|
||||
_, d.len = consumeUint64(b)
|
||||
d.nx = int(d.len) % chunk
|
||||
return nil
|
||||
}
|
||||
|
||||
// Size returns the size of hash digest
|
||||
func (d *digest) Size() int { return Size }
|
||||
|
||||
// BlockSize return the bytes of one block
|
||||
func (d *digest) BlockSize() int { return BlockSize }
|
||||
|
||||
func (d *digest) Write(p []byte) (nn int, err error) {
|
||||
nn = len(p)
|
||||
d.len += uint64(nn)
|
||||
// try to clear d.x
|
||||
if d.nx > 0 {
|
||||
n := copy(d.x[d.nx:], p)
|
||||
d.nx += n
|
||||
if d.nx == chunk {
|
||||
block(d, d.x[:])
|
||||
d.nx = 0
|
||||
}
|
||||
p = p[n:]
|
||||
}
|
||||
|
||||
if len(p) >= chunk {
|
||||
// n is multiple of chunk
|
||||
n := len(p) &^ (chunk - 1)
|
||||
block(d, p[:n])
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) > 0 {
|
||||
d.nx = copy(d.x[:], p)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Sum returns the digest without change the intenal states
|
||||
func (d *digest) Sum(in []byte) []byte {
|
||||
// make a copy
|
||||
d0 := *d
|
||||
hash := d0.checkSum()
|
||||
return append(in, hash[:]...)
|
||||
}
|
||||
|
||||
// Sum returns the SM3 checksum of the data.
|
||||
func Sum(data ...[]byte) [Size]byte {
|
||||
var d digest
|
||||
d.Reset()
|
||||
for _, x := range data {
|
||||
d.Write(x)
|
||||
}
|
||||
return d.checkSum()
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package sm3_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"xdx.jelly/xgcl/sm/sm3"
|
||||
)
|
||||
|
||||
// BenchmarkBlockGeneric 性能测试
|
||||
func BenchmarkBlockGeneric(b *testing.B) {
|
||||
d := sm3.NewDigest()
|
||||
buf := make([]byte, 10*1024*1024)
|
||||
b.SetBytes(int64(len(buf)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sm3.BlockGeneric(d, buf)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkBlockAVX2 性能测试
|
||||
func BenchmarkBlockAVX2(b *testing.B) {
|
||||
d := sm3.NewDigest()
|
||||
buf := make([]byte, 10*1024*1024)
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sm3.BlockAsmAVX2(d, buf)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
package sm3
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBlock(t *testing.T) {
|
||||
d := new(digest)
|
||||
d.Reset()
|
||||
p := make([]byte, 64)
|
||||
for i := range p {
|
||||
p[i] = 1
|
||||
}
|
||||
block(d, p)
|
||||
expect := [8]uint32{0xb9122804, 0xc515b3c2, 0xb34a42f1, 0x06edad4e, 0x52ecd5c7, 0x8545dd67, 0xf42b4275, 0x900ed3ad}
|
||||
assert.Equal(t, d.h, expect)
|
||||
}
|
||||
|
||||
// BenchmarkSM3 SM3性能测试
|
||||
//
|
||||
// goos: darwin
|
||||
// goarch: arm64
|
||||
// pkg: xdx.jelly/xgcl/sm/sm3
|
||||
// BenchmarkSM3
|
||||
// BenchmarkSM3-10 34 31783298 ns/op 329.91 MB/s 272 B/op 3 allocs/op
|
||||
// PASS
|
||||
// ok xdx.jelly/xgcl/sm/sm3 1.184s
|
||||
func BenchmarkSM3(b *testing.B) {
|
||||
buf := make([]byte, 10*1024*1024)
|
||||
d := New()
|
||||
b.SetBytes(int64(len(buf)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
d.Write(buf)
|
||||
d.Sum(nil)
|
||||
d.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
var sm3Tests = []struct {
|
||||
name string
|
||||
msg []byte
|
||||
iterations int
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
msg: []byte{},
|
||||
iterations: 1,
|
||||
want: "1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b",
|
||||
},
|
||||
{
|
||||
name: "short",
|
||||
msg: []byte("abc"),
|
||||
iterations: 1,
|
||||
want: "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0",
|
||||
},
|
||||
{
|
||||
name: "long",
|
||||
msg: []byte("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"),
|
||||
iterations: 1,
|
||||
want: "debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732",
|
||||
},
|
||||
{
|
||||
name: "longlong",
|
||||
msg: longMsg,
|
||||
iterations: 1,
|
||||
want: "c5c13a8f59a97cdeae64f16a2272a9e7dd228cb67912cce1fbe3616c954bcbf3",
|
||||
},
|
||||
}
|
||||
|
||||
func TestSm3(t *testing.T) {
|
||||
for _, test := range sm3Tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
d := New()
|
||||
for i := 0; i < test.iterations; i++ {
|
||||
for _, c := range test.msg {
|
||||
d.Write([]byte{c})
|
||||
}
|
||||
}
|
||||
s := fmt.Sprintf("%x", d.Sum(nil))
|
||||
assert.Equal(t, s, test.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSM3(t *testing.T) {
|
||||
data := make([]byte, 256)
|
||||
for i := range data {
|
||||
data[i] = byte(i)
|
||||
}
|
||||
for i := 0; i < len(data); i++ {
|
||||
digest := Sum(data[:i])
|
||||
fmt.Printf("%x\n", digest[:])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpeedReport(t *testing.T) {
|
||||
msg := make([]byte, 10*1024*1024)
|
||||
_, _ = rand.Read(msg)
|
||||
|
||||
start := time.Now()
|
||||
times := 100
|
||||
for i := 0; i < times; i++ {
|
||||
Sum(msg)
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
elapsed := end.Sub(start)
|
||||
t.Logf("SM3 digest speed: %.2f MBps\n", float64(times*len(msg))/float64(1024*1024)/elapsed.Seconds())
|
||||
}
|
||||
|
||||
var longMsg = []byte{
|
||||
0x41, 0x6C, 0x69, 0x63, 0x65, 0x42, 0x6F, 0x62,
|
||||
0x7C, 0xBA, 0x5B, 0x19, 0x06, 0x9E, 0xE6, 0x6A,
|
||||
0xA7, 0x9D, 0x49, 0x04, 0x13, 0xD1, 0x18, 0x46,
|
||||
0xB9, 0xBA, 0x76, 0xDD, 0x22, 0x56, 0x7F, 0x80,
|
||||
0x9C, 0xF2, 0x3B, 0x6D, 0x96, 0x4B, 0xB2, 0x65,
|
||||
0xA9, 0x76, 0x0C, 0x99, 0xCB, 0x6F, 0x70, 0x63,
|
||||
0x43, 0xFE, 0xD0, 0x56, 0x37, 0x08, 0x58, 0x64,
|
||||
0x95, 0x8D, 0x6C, 0x90, 0x90, 0x2A, 0xBA, 0x7D,
|
||||
0x40, 0x5F, 0xBE, 0xDF, 0x7B, 0x78, 0x15, 0x99,
|
||||
0x86, 0x1E, 0x91, 0x48, 0x5F, 0xB7, 0x62, 0x3D,
|
||||
0x27, 0x94, 0xF4, 0x95, 0x03, 0x1A, 0x35, 0x59,
|
||||
0x8B, 0x49, 0x3B, 0xD4, 0x5B, 0xE3, 0x78, 0x13,
|
||||
0xAB, 0xC7, 0x10, 0xFC, 0xC1, 0xF3, 0x44, 0x82,
|
||||
0x32, 0xD9, 0x06, 0xA4, 0x69, 0xEB, 0xC1, 0x21,
|
||||
0x6A, 0x80, 0x2A, 0x70, 0x52, 0xD5, 0x61, 0x7C,
|
||||
0xD4, 0x30, 0xFB, 0x56, 0xFB, 0xA7, 0x29, 0xD4,
|
||||
0x1D, 0x9B, 0xD6, 0x68, 0xE9, 0xEB, 0x96, 0x00,
|
||||
0x28, 0x54, 0x2F, 0xB6, 0x95, 0x4C, 0x84, 0xBE,
|
||||
0x6A, 0x5F, 0x29, 0x88, 0xA3, 0x1C, 0xB6, 0x81,
|
||||
0x7B, 0xA0, 0x78, 0x19, 0x66, 0xFA, 0x83, 0xD9,
|
||||
0x67, 0x3A, 0x95, 0x77, 0xD3, 0xC0, 0xC1, 0x34,
|
||||
0x5E, 0x27, 0xC1, 0x9F, 0xC0, 0x2E, 0xD9, 0xAE,
|
||||
0x37, 0xF5, 0xBB, 0x7B, 0xE9, 0xC0, 0x3C, 0x2B,
|
||||
0x87, 0xDE, 0x02, 0x75, 0x39, 0xCC, 0xF0, 0x3E,
|
||||
0x6B, 0x7D, 0x36, 0xDE, 0x4A, 0xB4, 0x5C, 0xD1,
|
||||
0xA1, 0xAB, 0xFC, 0xD3, 0x0C, 0x57, 0xDB, 0x0F,
|
||||
0x1A, 0x83, 0x8E, 0x3A, 0x8F, 0x2B, 0xF8, 0x23,
|
||||
0x47, 0x9C, 0x97, 0x8B, 0xD1, 0x37, 0x23, 0x05,
|
||||
0x06, 0xEA, 0x62, 0x49, 0xC8, 0x91, 0x04, 0x9E,
|
||||
0x34, 0x97, 0x47, 0x79, 0x13, 0xAB, 0x89, 0xF5,
|
||||
0xE2, 0x96, 0x0F, 0x38, 0x2B, 0x1B, 0x5C, 0x8E,
|
||||
0xE0, 0x9D, 0xE0, 0xFA, 0x49, 0x8B, 0xA9, 0x5C,
|
||||
0x44, 0x09, 0xD6, 0x30, 0xD3, 0x43, 0xDA, 0x40,
|
||||
0x4F, 0xEC, 0x93, 0x47, 0x2D, 0xA3, 0x3A, 0x4D,
|
||||
0xB6, 0x59, 0x90, 0x95, 0xC0, 0xCF, 0x89, 0x5E,
|
||||
0x3A, 0x7B, 0x99, 0x3E, 0xE5, 0xE4, 0xEB, 0xE3,
|
||||
0xB9, 0xAB, 0x7D, 0x7D, 0x5F, 0xF2, 0xA3, 0xD1,
|
||||
0x64, 0x7B, 0xA1, 0x54, 0xC3, 0xE8, 0xE1, 0x85,
|
||||
0xDF, 0xC3, 0x36, 0x57, 0xC1, 0xF1, 0x28, 0xD4,
|
||||
0x80, 0xF3, 0xF7, 0xE3, 0xF1, 0x68, 0x01, 0x20,
|
||||
0x80, 0x29, 0xE1, 0x94, 0x34, 0xC7, 0x33, 0xBB,
|
||||
0x73, 0xF2, 0x16, 0x93, 0xC6, 0x6F, 0xC2, 0x37,
|
||||
0x24, 0xDB, 0x26, 0x38, 0x0C, 0x52, 0x62, 0x23,
|
||||
0xC7, 0x05, 0xDA, 0xF6, 0xBA, 0x18, 0xB7, 0x63,
|
||||
0xA6, 0x86, 0x23, 0xC8, 0x6A, 0x63, 0x2B, 0x05,
|
||||
0x0F, 0x63, 0xA0, 0x71, 0xA6, 0xD6, 0x2E, 0xA4,
|
||||
0x5B, 0x59, 0xA1, 0x94, 0x2D, 0xFF, 0x53, 0x35,
|
||||
0xD1, 0xA2, 0x32, 0xC9, 0xC5, 0x66, 0x4F, 0xAD,
|
||||
0x5D, 0x6A, 0xF5, 0x4C, 0x11, 0x41, 0x8B, 0x0D,
|
||||
0x8C, 0x8E, 0x9D, 0x8D, 0x90, 0x57, 0x80, 0xD5,
|
||||
0x0E, 0x77, 0x90, 0x67, 0xF2, 0xC4, 0xB1, 0xC8,
|
||||
0xF8, 0x3A, 0x8B, 0x59, 0xD7, 0x35, 0xBB, 0x52,
|
||||
0xAF, 0x35, 0xF5, 0x67, 0x30, 0xBD, 0xE5, 0xAC,
|
||||
0x86, 0x1C, 0xCD, 0x99, 0x78, 0x61, 0x72, 0x67,
|
||||
0xCE, 0x4A, 0xD9, 0x78, 0x9F, 0x77, 0x73, 0x9E,
|
||||
0x62, 0xF2, 0xE5, 0x7B, 0x48, 0xC2, 0xFF, 0x26,
|
||||
0xD2, 0xE9, 0x0A, 0x79, 0xA1, 0xD8, 0x6B, 0x93,
|
||||
0x9B, 0x1C, 0xA0, 0x8F, 0x64, 0x71, 0x2E, 0x33,
|
||||
0xAE, 0xDA, 0x3F, 0x44, 0xBD, 0x6C, 0xB6, 0x33,
|
||||
0xE0, 0xF7, 0x22, 0x21, 0x1E, 0x34, 0x4D, 0x73,
|
||||
0xEC, 0x9B, 0xBE, 0xBC, 0x92, 0x14, 0x27, 0x65,
|
||||
0x6B, 0xA5, 0x84, 0xCE, 0x74, 0x2A, 0x2A, 0x3A,
|
||||
0xB4, 0x1C, 0x15, 0xD3, 0xEF, 0x94, 0xED, 0xEB,
|
||||
0x8E, 0xF7, 0x4A, 0x2B, 0xDC, 0xDA, 0xAE, 0xCC,
|
||||
0x09, 0xAB, 0xA5, 0x67, 0x98, 0x1F, 0x64, 0x37,
|
||||
0x10, 0x52, 0xD6, 0xE9, 0xD1, 0x3E, 0x38, 0x19,
|
||||
0x09, 0xDF, 0xF7, 0xB2, 0xB4, 0x1E, 0x13, 0xC9,
|
||||
0x87, 0xD0, 0xA9, 0x06, 0x84, 0x23, 0xB7, 0x69,
|
||||
0x48, 0x0D, 0xAC, 0xCE, 0x6A, 0x06, 0xF4, 0x92,
|
||||
0x5F, 0xFE, 0xB9, 0x2A, 0xD8, 0x70, 0xF9, 0x7D,
|
||||
0xC0, 0x89, 0x31, 0x14, 0xDA, 0x22, 0xA4, 0x4D,
|
||||
0xBC, 0x9E, 0x7A, 0x8B, 0x6C, 0xA3, 0x1A, 0x0C,
|
||||
0xF0, 0x46, 0x72, 0x65, 0xA1, 0xFB, 0x48, 0xC7,
|
||||
0x2C, 0x5C, 0x3B, 0x37, 0xE4, 0xF2, 0xFF, 0x83,
|
||||
0xDB, 0x33, 0xD9, 0x8C, 0x03, 0x17, 0xBC, 0xBB,
|
||||
0xBB, 0xF4, 0xAC, 0x6D, 0xF6, 0xB8, 0x9E, 0xCA,
|
||||
0x58, 0x26, 0x8B, 0x28, 0x00, 0x45, 0xE6, 0x12,
|
||||
0x6C, 0xED, 0x9E, 0x2D, 0x7C, 0x9C, 0xD3, 0xD5,
|
||||
0xAD, 0x63, 0x0D, 0xEF, 0xAB, 0x0B, 0x83, 0x15,
|
||||
0x06, 0x21, 0x80, 0x37, 0xEE, 0x0F, 0x86, 0x1C,
|
||||
0xF9, 0xB4, 0x3C, 0x78, 0x43, 0x4A, 0xEC, 0x38,
|
||||
0x0A, 0xE7, 0xBF, 0x3E, 0x1A, 0xEC, 0x0C, 0xB6,
|
||||
0x7A, 0x03, 0x44, 0x09, 0x06, 0xC7, 0xDF, 0xB3,
|
||||
0xBC, 0xD4, 0xB6, 0xEE, 0xEB, 0xB7, 0xE3, 0x71,
|
||||
0xF0, 0x09, 0x4A, 0xD4, 0xA8, 0x16, 0x08, 0x8D,
|
||||
0x98, 0xDB, 0xC7, 0x91, 0xD0, 0x67, 0x1C, 0xAC,
|
||||
0xA1, 0x22, 0x36, 0xCD, 0xF8, 0xF3, 0x9E, 0x15,
|
||||
0xAE, 0xB9, 0x6F, 0xAE, 0xB3, 0x96, 0x06, 0xD5,
|
||||
0xB0, 0x4A, 0xC5, 0x81, 0x74, 0x6A, 0x66, 0x3D,
|
||||
0x00, 0xDD, 0x2B, 0x74, 0x16, 0xBA, 0xA9, 0x11,
|
||||
0x72, 0xE8, 0x9D, 0x53, 0x09, 0xD8, 0x34, 0xF7,
|
||||
0x8C, 0x1E, 0x31, 0xB4, 0x48, 0x3B, 0xB9, 0x71,
|
||||
0x85, 0x93, 0x1B, 0xAD, 0x7B, 0xE1, 0xB9, 0xB5,
|
||||
0x7E, 0xBA, 0xC0, 0x34, 0x9F, 0x85, 0x44, 0x46,
|
||||
0x9E, 0x60, 0xC3, 0x2F, 0x60, 0x75, 0xFB, 0x04,
|
||||
0x68, 0xA6, 0x81, 0x47, 0xFF, 0x01, 0x35, 0x37,
|
||||
0xDF, 0x79, 0x2F, 0xFC, 0xE0, 0x24, 0xF8, 0x57,
|
||||
0x10, 0xCC, 0x2B, 0x56, 0x1A, 0x62, 0xB6, 0x2D,
|
||||
0xA3, 0x6A, 0xEF, 0xD6, 0x08, 0x50, 0x71, 0x4F,
|
||||
0x49, 0x17, 0x0F, 0xD9, 0x4A, 0x00, 0x10, 0xC6,
|
||||
0xD4, 0xB6, 0x51, 0xB6, 0x4F, 0x3A, 0x3A, 0x5E,
|
||||
0x58, 0xC9, 0x68, 0x7B, 0xED, 0xDC, 0xD9, 0xE4,
|
||||
0xFE, 0xDA, 0xB1, 0x6B, 0x88, 0x4D, 0x1F, 0xE6,
|
||||
0xDF, 0xA1, 0x17, 0xB2, 0xAB, 0x82, 0x1F, 0x74,
|
||||
0xE0, 0xBF, 0x7A, 0xCD, 0xA2, 0x26, 0x98, 0x59,
|
||||
0x2A, 0x43, 0x09, 0x68, 0xF1, 0x60, 0x86, 0x06,
|
||||
0x19, 0x04, 0xCE, 0x20, 0x18, 0x47, 0x93, 0x4B,
|
||||
0x11, 0xCA, 0x0F, 0x9E, 0x95, 0x28, 0xF5, 0xA9,
|
||||
0xD0, 0xCE, 0x8F, 0x01, 0x5C, 0x9A, 0xEA, 0x79,
|
||||
0x93, 0x4F, 0xDD, 0xA6, 0xD3, 0xAB, 0x48, 0xC8,
|
||||
0x57, 0x1C, 0xE2, 0x35, 0x4B, 0x79, 0x74, 0x2A,
|
||||
0xA4, 0x98, 0xCB, 0x8C, 0xDD, 0xE6, 0xBD, 0x1F,
|
||||
0xA5, 0x94, 0x63, 0x45, 0xA1, 0xA6, 0x52, 0xF6,
|
||||
0xA7, 0x6B, 0x67, 0x77, 0xAD, 0x87, 0xC9, 0x12,
|
||||
0x4C, 0x7D, 0x70, 0x65, 0xF7, 0x48, 0x08, 0xDB,
|
||||
0x2E, 0x80, 0x37, 0x1C, 0x70, 0x47, 0x15, 0x80,
|
||||
0xB0, 0xC7, 0xC4, 0x57, 0xA7, 0x9E, 0xA5, 0xE7,
|
||||
0x24, 0x2F, 0xA3, 0x1F, 0xF8, 0xE1, 0x39, 0xFA,
|
||||
0xE1, 0x69, 0xA1, 0x69, 0x92, 0xF5, 0xF0, 0x29,
|
||||
0x16, 0x26, 0x64, 0xCE, 0x78, 0xB3, 0x33, 0x32,
|
||||
0x4B, 0x3B, 0xDB, 0x4C, 0x68, 0x2B, 0xF9, 0xB2,
|
||||
0x06, 0x26, 0xD6, 0x4D, 0xCE, 0x60, 0x3F, 0x33,
|
||||
0x2E, 0x95, 0x93, 0xF6, 0x2B, 0x67, 0xA6, 0xB0,
|
||||
0x02, 0xDE, 0xB6, 0xDD, 0x2E, 0x7D, 0x4F, 0xAD,
|
||||
0x3F, 0x33, 0xC3, 0x8F, 0x20, 0x2D, 0xE2, 0x04,
|
||||
0x53, 0x27, 0x49, 0x06, 0x11, 0xB2, 0xAE, 0x6F,
|
||||
0x84, 0x9C, 0xF7, 0x79, 0xB9, 0xB7, 0x4A, 0xD9,
|
||||
0xBA, 0x6C, 0xF3, 0x97, 0xF6, 0x13, 0x26, 0x12,
|
||||
0x07, 0x77, 0xCE, 0x46, 0x92, 0xF8, 0x5D, 0xC2,
|
||||
0xAD, 0xC2, 0x69, 0xD1, 0xB6, 0x23, 0x32, 0x58,
|
||||
0x2D, 0x82, 0x31, 0x32, 0xA9, 0x71, 0x27, 0x54,
|
||||
0x77, 0xA0, 0xCF, 0x1D, 0xCC, 0xF4, 0xB2, 0xBF,
|
||||
0x09, 0x6D, 0x91, 0x10, 0xF7, 0x4E, 0x2A, 0x01,
|
||||
0xB1, 0xED, 0x06, 0x50, 0x23, 0x33, 0xB2, 0xAB,
|
||||
0x1A, 0xE6, 0x97, 0xEA, 0x34, 0xF2, 0xEF, 0x8C,
|
||||
0x6E, 0x47, 0xB0, 0x43, 0x18, 0x31, 0x70, 0x6C,
|
||||
0xB5, 0xAF, 0xCD, 0x75, 0x75, 0x4F, 0xA7, 0x95,
|
||||
0x28, 0xF6, 0x5B, 0x36, 0x51, 0xE1, 0x84, 0xBC,
|
||||
0xED, 0x03, 0x06, 0x61, 0xEE, 0x4A, 0x8D, 0x67,
|
||||
0x0F, 0xBA, 0xE2, 0x67, 0x96, 0xE8, 0xCD, 0xB6,
|
||||
0x6F, 0x38, 0x8E, 0xD6, 0x64, 0x4A, 0xF8, 0x51,
|
||||
0x88, 0x5C, 0x7F, 0x92, 0x4C, 0xC7, 0xCB, 0x20,
|
||||
0x96, 0x8A, 0xA5, 0x0E, 0x82, 0x30, 0xA3, 0xB3,
|
||||
0x9C, 0x2B, 0xB5, 0xDD, 0x4D, 0x75, 0x3D, 0x94,
|
||||
0xBE, 0x5D, 0xD9, 0xA4, 0x27, 0x2C, 0xF8, 0x27,
|
||||
0x0D, 0xA6, 0x49, 0xCB, 0x8A, 0x63, 0x17, 0x2F,
|
||||
0x8F, 0xB0, 0x28, 0xCD, 0x95, 0x1E, 0x76, 0x21,
|
||||
0x58, 0x24, 0xA4, 0xEE, 0x28, 0x40, 0x5D, 0x3C,
|
||||
0x5E, 0x5D, 0xFD, 0xA6, 0xC7, 0xCE, 0x29, 0x3F,
|
||||
0x4A, 0x40, 0xAC, 0x8F, 0xC5, 0xB7, 0x16, 0x8F,
|
||||
0xA5, 0x4A, 0xD3, 0xD0, 0xB8, 0x1A, 0x0F, 0x8F,
|
||||
0x50, 0xC1, 0x64, 0x36, 0x6C, 0xCD, 0xEC, 0x1C,
|
||||
0x9A, 0x40, 0xDC, 0xE9, 0xF0, 0xA3, 0x11, 0x33,
|
||||
0x35, 0xD8, 0x9E, 0xAE, 0xB3, 0x6F, 0x4D, 0x31,
|
||||
0xBB, 0x67, 0x13, 0x06, 0x4C, 0xDA, 0x88, 0x35,
|
||||
0xE2, 0xAA, 0x45, 0x29, 0xF4, 0x21, 0x29, 0x32,
|
||||
0x7C, 0x6F, 0x7E, 0x8A, 0xB7, 0x60, 0x65, 0x4D,
|
||||
0x58, 0xD1, 0x7E, 0x44, 0x8F, 0x6D, 0x5C, 0xBC,
|
||||
0xA6, 0x6B, 0xD7, 0xE3, 0x38, 0x10, 0xD2, 0x70,
|
||||
0xDD, 0x3B, 0x94, 0x36, 0xB1, 0xBF, 0x46, 0xB9,
|
||||
0xA1, 0x7C, 0x9D, 0x11, 0xA5, 0xA6, 0xB1, 0x48,
|
||||
0, 0, 0, 1,
|
||||
}
|
||||
Reference in New Issue
Block a user