|
@@ -0,0 +1,931 @@
|
|
|
|
|
+// Copyright 2018 The Go Authors. All rights reserved.
|
|
|
|
|
+// Use of this source code is governed by a BSD-style
|
|
|
|
|
+// license that can be found in the LICENSE file.
|
|
|
|
|
+
|
|
|
|
|
+// +build s390x,go1.11,!gccgo,!appengine
|
|
|
|
|
+
|
|
|
|
|
+#include "textflag.h"
|
|
|
|
|
+
|
|
|
|
|
+// Implementation of Poly1305 using the vector facility (vx) and the VMSL instruction.
|
|
|
|
|
+
|
|
|
|
|
+// constants
|
|
|
|
|
+#define EX0 V1
|
|
|
|
|
+#define EX1 V2
|
|
|
|
|
+#define EX2 V3
|
|
|
|
|
+
|
|
|
|
|
+// temporaries
|
|
|
|
|
+#define T_0 V4
|
|
|
|
|
+#define T_1 V5
|
|
|
|
|
+#define T_2 V6
|
|
|
|
|
+#define T_3 V7
|
|
|
|
|
+#define T_4 V8
|
|
|
|
|
+#define T_5 V9
|
|
|
|
|
+#define T_6 V10
|
|
|
|
|
+#define T_7 V11
|
|
|
|
|
+#define T_8 V12
|
|
|
|
|
+#define T_9 V13
|
|
|
|
|
+#define T_10 V14
|
|
|
|
|
+
|
|
|
|
|
+// r**2 & r**4
|
|
|
|
|
+#define R_0 V15
|
|
|
|
|
+#define R_1 V16
|
|
|
|
|
+#define R_2 V17
|
|
|
|
|
+#define R5_1 V18
|
|
|
|
|
+#define R5_2 V19
|
|
|
|
|
+// key (r)
|
|
|
|
|
+#define RSAVE_0 R7
|
|
|
|
|
+#define RSAVE_1 R8
|
|
|
|
|
+#define RSAVE_2 R9
|
|
|
|
|
+#define R5SAVE_1 R10
|
|
|
|
|
+#define R5SAVE_2 R11
|
|
|
|
|
+
|
|
|
|
|
+// message block
|
|
|
|
|
+#define M0 V20
|
|
|
|
|
+#define M1 V21
|
|
|
|
|
+#define M2 V22
|
|
|
|
|
+#define M3 V23
|
|
|
|
|
+#define M4 V24
|
|
|
|
|
+#define M5 V25
|
|
|
|
|
+
|
|
|
|
|
+// accumulator
|
|
|
|
|
+#define H0_0 V26
|
|
|
|
|
+#define H1_0 V27
|
|
|
|
|
+#define H2_0 V28
|
|
|
|
|
+#define H0_1 V29
|
|
|
|
|
+#define H1_1 V30
|
|
|
|
|
+#define H2_1 V31
|
|
|
|
|
+
|
|
|
|
|
+GLOBL ·keyMask<>(SB), RODATA, $16
|
|
|
|
|
+DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f
|
|
|
|
|
+DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f
|
|
|
|
|
+
|
|
|
|
|
+GLOBL ·bswapMask<>(SB), RODATA, $16
|
|
|
|
|
+DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908
|
|
|
|
|
+DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100
|
|
|
|
|
+
|
|
|
|
|
+GLOBL ·constants<>(SB), RODATA, $48
|
|
|
|
|
+// EX0
|
|
|
|
|
+DATA ·constants<>+0(SB)/8, $0x18191a1b1c1d1e1f
|
|
|
|
|
+DATA ·constants<>+8(SB)/8, $0x0000050403020100
|
|
|
|
|
+// EX1
|
|
|
|
|
+DATA ·constants<>+16(SB)/8, $0x18191a1b1c1d1e1f
|
|
|
|
|
+DATA ·constants<>+24(SB)/8, $0x00000a0908070605
|
|
|
|
|
+// EX2
|
|
|
|
|
+DATA ·constants<>+32(SB)/8, $0x18191a1b1c1d1e1f
|
|
|
|
|
+DATA ·constants<>+40(SB)/8, $0x0000000f0e0d0c0b
|
|
|
|
|
+
|
|
|
|
|
+GLOBL ·c<>(SB), RODATA, $48
|
|
|
|
|
+// EX0
|
|
|
|
|
+DATA ·c<>+0(SB)/8, $0x0000050403020100
|
|
|
|
|
+DATA ·c<>+8(SB)/8, $0x0000151413121110
|
|
|
|
|
+// EX1
|
|
|
|
|
+DATA ·c<>+16(SB)/8, $0x00000a0908070605
|
|
|
|
|
+DATA ·c<>+24(SB)/8, $0x00001a1918171615
|
|
|
|
|
+// EX2
|
|
|
|
|
+DATA ·c<>+32(SB)/8, $0x0000000f0e0d0c0b
|
|
|
|
|
+DATA ·c<>+40(SB)/8, $0x0000001f1e1d1c1b
|
|
|
|
|
+
|
|
|
|
|
+GLOBL ·reduce<>(SB), RODATA, $32
|
|
|
|
|
+// 44 bit
|
|
|
|
|
+DATA ·reduce<>+0(SB)/8, $0x0
|
|
|
|
|
+DATA ·reduce<>+8(SB)/8, $0xfffffffffff
|
|
|
|
|
+// 42 bit
|
|
|
|
|
+DATA ·reduce<>+16(SB)/8, $0x0
|
|
|
|
|
+DATA ·reduce<>+24(SB)/8, $0x3ffffffffff
|
|
|
|
|
+
|
|
|
|
|
+// h = (f*g) % (2**130-5) [partial reduction]
|
|
|
|
|
+// uses T_0...T_9 temporary registers
|
|
|
|
|
+// input: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2
|
|
|
|
|
+// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9
|
|
|
|
|
+// output: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2
|
|
|
|
|
+#define MULTIPLY(m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
|
|
|
|
|
+ \ // Eliminate the dependency for the last 2 VMSLs
|
|
|
|
|
+ VMSLG m02_0, r_2, m4_2, m4_2 \
|
|
|
|
|
+ VMSLG m13_0, r_2, m5_2, m5_2 \ // 8 VMSLs pipelined
|
|
|
|
|
+ VMSLG m02_0, r_0, m4_0, m4_0 \
|
|
|
|
|
+ VMSLG m02_1, r5_2, V0, T_0 \
|
|
|
|
|
+ VMSLG m02_0, r_1, m4_1, m4_1 \
|
|
|
|
|
+ VMSLG m02_1, r_0, V0, T_1 \
|
|
|
|
|
+ VMSLG m02_1, r_1, V0, T_2 \
|
|
|
|
|
+ VMSLG m02_2, r5_1, V0, T_3 \
|
|
|
|
|
+ VMSLG m02_2, r5_2, V0, T_4 \
|
|
|
|
|
+ VMSLG m13_0, r_0, m5_0, m5_0 \
|
|
|
|
|
+ VMSLG m13_1, r5_2, V0, T_5 \
|
|
|
|
|
+ VMSLG m13_0, r_1, m5_1, m5_1 \
|
|
|
|
|
+ VMSLG m13_1, r_0, V0, T_6 \
|
|
|
|
|
+ VMSLG m13_1, r_1, V0, T_7 \
|
|
|
|
|
+ VMSLG m13_2, r5_1, V0, T_8 \
|
|
|
|
|
+ VMSLG m13_2, r5_2, V0, T_9 \
|
|
|
|
|
+ VMSLG m02_2, r_0, m4_2, m4_2 \
|
|
|
|
|
+ VMSLG m13_2, r_0, m5_2, m5_2 \
|
|
|
|
|
+ VAQ m4_0, T_0, m02_0 \
|
|
|
|
|
+ VAQ m4_1, T_1, m02_1 \
|
|
|
|
|
+ VAQ m5_0, T_5, m13_0 \
|
|
|
|
|
+ VAQ m5_1, T_6, m13_1 \
|
|
|
|
|
+ VAQ m02_0, T_3, m02_0 \
|
|
|
|
|
+ VAQ m02_1, T_4, m02_1 \
|
|
|
|
|
+ VAQ m13_0, T_8, m13_0 \
|
|
|
|
|
+ VAQ m13_1, T_9, m13_1 \
|
|
|
|
|
+ VAQ m4_2, T_2, m02_2 \
|
|
|
|
|
+ VAQ m5_2, T_7, m13_2 \
|
|
|
|
|
+
|
|
|
|
|
+// SQUARE uses three limbs of r and r_2*5 to output square of r
|
|
|
|
|
+// uses T_1, T_5 and T_7 temporary registers
|
|
|
|
|
+// input: r_0, r_1, r_2, r5_2
|
|
|
|
|
+// temp: TEMP0, TEMP1, TEMP2
|
|
|
|
|
+// output: p0, p1, p2
|
|
|
|
|
+#define SQUARE(r_0, r_1, r_2, r5_2, p0, p1, p2, TEMP0, TEMP1, TEMP2) \
|
|
|
|
|
+ VMSLG r_0, r_0, p0, p0 \
|
|
|
|
|
+ VMSLG r_1, r5_2, V0, TEMP0 \
|
|
|
|
|
+ VMSLG r_2, r5_2, p1, p1 \
|
|
|
|
|
+ VMSLG r_0, r_1, V0, TEMP1 \
|
|
|
|
|
+ VMSLG r_1, r_1, p2, p2 \
|
|
|
|
|
+ VMSLG r_0, r_2, V0, TEMP2 \
|
|
|
|
|
+ VAQ TEMP0, p0, p0 \
|
|
|
|
|
+ VAQ TEMP1, p1, p1 \
|
|
|
|
|
+ VAQ TEMP2, p2, p2 \
|
|
|
|
|
+ VAQ TEMP0, p0, p0 \
|
|
|
|
|
+ VAQ TEMP1, p1, p1 \
|
|
|
|
|
+ VAQ TEMP2, p2, p2 \
|
|
|
|
|
+
|
|
|
|
|
+// carry h0->h1->h2->h0 || h3->h4->h5->h3
|
|
|
|
|
+// uses T_2, T_4, T_5, T_7, T_8, T_9
|
|
|
|
|
+// t6, t7, t8, t9, t10, t11
|
|
|
|
|
+// input: h0, h1, h2, h3, h4, h5
|
|
|
|
|
+// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
|
|
|
|
|
+// output: h0, h1, h2, h3, h4, h5
|
|
|
|
|
+#define REDUCE(h0, h1, h2, h3, h4, h5, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) \
|
|
|
|
|
+ VLM (R12), t6, t7 \ // 44 and 42 bit clear mask
|
|
|
|
|
+ VLEIB $7, $0x28, t10 \ // 5 byte shift mask
|
|
|
|
|
+ VREPIB $4, t8 \ // 4 bit shift mask
|
|
|
|
|
+ VREPIB $2, t11 \ // 2 bit shift mask
|
|
|
|
|
+ VSRLB t10, h0, t0 \ // h0 byte shift
|
|
|
|
|
+ VSRLB t10, h1, t1 \ // h1 byte shift
|
|
|
|
|
+ VSRLB t10, h2, t2 \ // h2 byte shift
|
|
|
|
|
+ VSRLB t10, h3, t3 \ // h3 byte shift
|
|
|
|
|
+ VSRLB t10, h4, t4 \ // h4 byte shift
|
|
|
|
|
+ VSRLB t10, h5, t5 \ // h5 byte shift
|
|
|
|
|
+ VSRL t8, t0, t0 \ // h0 bit shift
|
|
|
|
|
+ VSRL t8, t1, t1 \ // h2 bit shift
|
|
|
|
|
+ VSRL t11, t2, t2 \ // h2 bit shift
|
|
|
|
|
+ VSRL t8, t3, t3 \ // h3 bit shift
|
|
|
|
|
+ VSRL t8, t4, t4 \ // h4 bit shift
|
|
|
|
|
+ VESLG $2, t2, t9 \ // h2 carry x5
|
|
|
|
|
+ VSRL t11, t5, t5 \ // h5 bit shift
|
|
|
|
|
+ VN t6, h0, h0 \ // h0 clear carry
|
|
|
|
|
+ VAQ t2, t9, t2 \ // h2 carry x5
|
|
|
|
|
+ VESLG $2, t5, t9 \ // h5 carry x5
|
|
|
|
|
+ VN t6, h1, h1 \ // h1 clear carry
|
|
|
|
|
+ VN t7, h2, h2 \ // h2 clear carry
|
|
|
|
|
+ VAQ t5, t9, t5 \ // h5 carry x5
|
|
|
|
|
+ VN t6, h3, h3 \ // h3 clear carry
|
|
|
|
|
+ VN t6, h4, h4 \ // h4 clear carry
|
|
|
|
|
+ VN t7, h5, h5 \ // h5 clear carry
|
|
|
|
|
+ VAQ t0, h1, h1 \ // h0->h1
|
|
|
|
|
+ VAQ t3, h4, h4 \ // h3->h4
|
|
|
|
|
+ VAQ t1, h2, h2 \ // h1->h2
|
|
|
|
|
+ VAQ t4, h5, h5 \ // h4->h5
|
|
|
|
|
+ VAQ t2, h0, h0 \ // h2->h0
|
|
|
|
|
+ VAQ t5, h3, h3 \ // h5->h3
|
|
|
|
|
+ VREPG $1, t6, t6 \ // 44 and 42 bit masks across both halves
|
|
|
|
|
+ VREPG $1, t7, t7 \
|
|
|
|
|
+ VSLDB $8, h0, h0, h0 \ // set up [h0/1/2, h3/4/5]
|
|
|
|
|
+ VSLDB $8, h1, h1, h1 \
|
|
|
|
|
+ VSLDB $8, h2, h2, h2 \
|
|
|
|
|
+ VO h0, h3, h3 \
|
|
|
|
|
+ VO h1, h4, h4 \
|
|
|
|
|
+ VO h2, h5, h5 \
|
|
|
|
|
+ VESRLG $44, h3, t0 \ // 44 bit shift right
|
|
|
|
|
+ VESRLG $44, h4, t1 \
|
|
|
|
|
+ VESRLG $42, h5, t2 \
|
|
|
|
|
+ VN t6, h3, h3 \ // clear carry bits
|
|
|
|
|
+ VN t6, h4, h4 \
|
|
|
|
|
+ VN t7, h5, h5 \
|
|
|
|
|
+ VESLG $2, t2, t9 \ // multiply carry by 5
|
|
|
|
|
+ VAQ t9, t2, t2 \
|
|
|
|
|
+ VAQ t0, h4, h4 \
|
|
|
|
|
+ VAQ t1, h5, h5 \
|
|
|
|
|
+ VAQ t2, h3, h3 \
|
|
|
|
|
+
|
|
|
|
|
+// carry h0->h1->h2->h0
|
|
|
|
|
+// input: h0, h1, h2
|
|
|
|
|
+// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8
|
|
|
|
|
+// output: h0, h1, h2
|
|
|
|
|
+#define REDUCE2(h0, h1, h2, t0, t1, t2, t3, t4, t5, t6, t7, t8) \
|
|
|
|
|
+ VLEIB $7, $0x28, t3 \ // 5 byte shift mask
|
|
|
|
|
+ VREPIB $4, t4 \ // 4 bit shift mask
|
|
|
|
|
+ VREPIB $2, t7 \ // 2 bit shift mask
|
|
|
|
|
+ VGBM $0x003F, t5 \ // mask to clear carry bits
|
|
|
|
|
+ VSRLB t3, h0, t0 \
|
|
|
|
|
+ VSRLB t3, h1, t1 \
|
|
|
|
|
+ VSRLB t3, h2, t2 \
|
|
|
|
|
+ VESRLG $4, t5, t5 \ // 44 bit clear mask
|
|
|
|
|
+ VSRL t4, t0, t0 \
|
|
|
|
|
+ VSRL t4, t1, t1 \
|
|
|
|
|
+ VSRL t7, t2, t2 \
|
|
|
|
|
+ VESRLG $2, t5, t6 \ // 42 bit clear mask
|
|
|
|
|
+ VESLG $2, t2, t8 \
|
|
|
|
|
+ VAQ t8, t2, t2 \
|
|
|
|
|
+ VN t5, h0, h0 \
|
|
|
|
|
+ VN t5, h1, h1 \
|
|
|
|
|
+ VN t6, h2, h2 \
|
|
|
|
|
+ VAQ t0, h1, h1 \
|
|
|
|
|
+ VAQ t1, h2, h2 \
|
|
|
|
|
+ VAQ t2, h0, h0 \
|
|
|
|
|
+ VSRLB t3, h0, t0 \
|
|
|
|
|
+ VSRLB t3, h1, t1 \
|
|
|
|
|
+ VSRLB t3, h2, t2 \
|
|
|
|
|
+ VSRL t4, t0, t0 \
|
|
|
|
|
+ VSRL t4, t1, t1 \
|
|
|
|
|
+ VSRL t7, t2, t2 \
|
|
|
|
|
+ VN t5, h0, h0 \
|
|
|
|
|
+ VN t5, h1, h1 \
|
|
|
|
|
+ VESLG $2, t2, t8 \
|
|
|
|
|
+ VN t6, h2, h2 \
|
|
|
|
|
+ VAQ t0, h1, h1 \
|
|
|
|
|
+ VAQ t8, t2, t2 \
|
|
|
|
|
+ VAQ t1, h2, h2 \
|
|
|
|
|
+ VAQ t2, h0, h0 \
|
|
|
|
|
+
|
|
|
|
|
+// expands two message blocks into the lower halfs of the d registers
|
|
|
|
|
+// moves the contents of the d registers into upper halfs
|
|
|
|
|
+// input: in1, in2, d0, d1, d2, d3, d4, d5
|
|
|
|
|
+// temp: TEMP0, TEMP1, TEMP2, TEMP3
|
|
|
|
|
+// output: d0, d1, d2, d3, d4, d5
|
|
|
|
|
+#define EXPACC(in1, in2, d0, d1, d2, d3, d4, d5, TEMP0, TEMP1, TEMP2, TEMP3) \
|
|
|
|
|
+ VGBM $0xff3f, TEMP0 \
|
|
|
|
|
+ VGBM $0xff1f, TEMP1 \
|
|
|
|
|
+ VESLG $4, d1, TEMP2 \
|
|
|
|
|
+ VESLG $4, d4, TEMP3 \
|
|
|
|
|
+ VESRLG $4, TEMP0, TEMP0 \
|
|
|
|
|
+ VPERM in1, d0, EX0, d0 \
|
|
|
|
|
+ VPERM in2, d3, EX0, d3 \
|
|
|
|
|
+ VPERM in1, d2, EX2, d2 \
|
|
|
|
|
+ VPERM in2, d5, EX2, d5 \
|
|
|
|
|
+ VPERM in1, TEMP2, EX1, d1 \
|
|
|
|
|
+ VPERM in2, TEMP3, EX1, d4 \
|
|
|
|
|
+ VN TEMP0, d0, d0 \
|
|
|
|
|
+ VN TEMP0, d3, d3 \
|
|
|
|
|
+ VESRLG $4, d1, d1 \
|
|
|
|
|
+ VESRLG $4, d4, d4 \
|
|
|
|
|
+ VN TEMP1, d2, d2 \
|
|
|
|
|
+ VN TEMP1, d5, d5 \
|
|
|
|
|
+ VN TEMP0, d1, d1 \
|
|
|
|
|
+ VN TEMP0, d4, d4 \
|
|
|
|
|
+
|
|
|
|
|
+// expands one message block into the lower halfs of the d registers
|
|
|
|
|
+// moves the contents of the d registers into upper halfs
|
|
|
|
|
+// input: in, d0, d1, d2
|
|
|
|
|
+// temp: TEMP0, TEMP1, TEMP2
|
|
|
|
|
+// output: d0, d1, d2
|
|
|
|
|
+#define EXPACC2(in, d0, d1, d2, TEMP0, TEMP1, TEMP2) \
|
|
|
|
|
+ VGBM $0xff3f, TEMP0 \
|
|
|
|
|
+ VESLG $4, d1, TEMP2 \
|
|
|
|
|
+ VGBM $0xff1f, TEMP1 \
|
|
|
|
|
+ VPERM in, d0, EX0, d0 \
|
|
|
|
|
+ VESRLG $4, TEMP0, TEMP0 \
|
|
|
|
|
+ VPERM in, d2, EX2, d2 \
|
|
|
|
|
+ VPERM in, TEMP2, EX1, d1 \
|
|
|
|
|
+ VN TEMP0, d0, d0 \
|
|
|
|
|
+ VN TEMP1, d2, d2 \
|
|
|
|
|
+ VESRLG $4, d1, d1 \
|
|
|
|
|
+ VN TEMP0, d1, d1 \
|
|
|
|
|
+
|
|
|
|
|
+// pack h2:h0 into h1:h0 (no carry)
|
|
|
|
|
+// input: h0, h1, h2
|
|
|
|
|
+// output: h0, h1, h2
|
|
|
|
|
+#define PACK(h0, h1, h2) \
|
|
|
|
|
+ VMRLG h1, h2, h2 \ // copy h1 to upper half h2
|
|
|
|
|
+ VESLG $44, h1, h1 \ // shift limb 1 44 bits, leaving 20
|
|
|
|
|
+ VO h0, h1, h0 \ // combine h0 with 20 bits from limb 1
|
|
|
|
|
+ VESRLG $20, h2, h1 \ // put top 24 bits of limb 1 into h1
|
|
|
|
|
+ VLEIG $1, $0, h1 \ // clear h2 stuff from lower half of h1
|
|
|
|
|
+ VO h0, h1, h0 \ // h0 now has 88 bits (limb 0 and 1)
|
|
|
|
|
+ VLEIG $0, $0, h2 \ // clear upper half of h2
|
|
|
|
|
+ VESRLG $40, h2, h1 \ // h1 now has upper two bits of result
|
|
|
|
|
+ VLEIB $7, $88, h1 \ // for byte shift (11 bytes)
|
|
|
|
|
+ VSLB h1, h2, h2 \ // shift h2 11 bytes to the left
|
|
|
|
|
+ VO h0, h2, h0 \ // combine h0 with 20 bits from limb 1
|
|
|
|
|
+ VLEIG $0, $0, h1 \ // clear upper half of h1
|
|
|
|
|
+
|
|
|
|
|
+// if h > 2**130-5 then h -= 2**130-5
|
|
|
|
|
+// input: h0, h1
|
|
|
|
|
+// temp: t0, t1, t2
|
|
|
|
|
+// output: h0
|
|
|
|
|
+#define MOD(h0, h1, t0, t1, t2) \
|
|
|
|
|
+ VZERO t0 \
|
|
|
|
|
+ VLEIG $1, $5, t0 \
|
|
|
|
|
+ VACCQ h0, t0, t1 \
|
|
|
|
|
+ VAQ h0, t0, t0 \
|
|
|
|
|
+ VONE t2 \
|
|
|
|
|
+ VLEIG $1, $-4, t2 \
|
|
|
|
|
+ VAQ t2, t1, t1 \
|
|
|
|
|
+ VACCQ h1, t1, t1 \
|
|
|
|
|
+ VONE t2 \
|
|
|
|
|
+ VAQ t2, t1, t1 \
|
|
|
|
|
+ VN h0, t1, t2 \
|
|
|
|
|
+ VNC t0, t1, t1 \
|
|
|
|
|
+ VO t1, t2, h0 \
|
|
|
|
|
+
|
|
|
|
|
+// func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
|
|
|
|
+TEXT ·poly1305vmsl(SB), $0-32
|
|
|
|
|
+ // This code processes 6 + up to 4 blocks (32 bytes) per iteration
|
|
|
|
|
+ // using the algorithm described in:
|
|
|
|
|
+ // NEON crypto, Daniel J. Bernstein & Peter Schwabe
|
|
|
|
|
+ // https://cryptojedi.org/papers/neoncrypto-20120320.pdf
|
|
|
|
|
+ // And as moddified for VMSL as described in
|
|
|
|
|
+ // Accelerating Poly1305 Cryptographic Message Authentication on the z14
|
|
|
|
|
+ // O'Farrell et al, CASCON 2017, p48-55
|
|
|
|
|
+ // https://ibm.ent.box.com/s/jf9gedj0e9d2vjctfyh186shaztavnht
|
|
|
|
|
+
|
|
|
|
|
+ LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key
|
|
|
|
|
+ VZERO V0 // c
|
|
|
|
|
+
|
|
|
|
|
+ // load EX0, EX1 and EX2
|
|
|
|
|
+ MOVD $·constants<>(SB), R5
|
|
|
|
|
+ VLM (R5), EX0, EX2 // c
|
|
|
|
|
+
|
|
|
|
|
+ // setup r
|
|
|
|
|
+ VL (R4), T_0
|
|
|
|
|
+ MOVD $·keyMask<>(SB), R6
|
|
|
|
|
+ VL (R6), T_1
|
|
|
|
|
+ VN T_0, T_1, T_0
|
|
|
|
|
+ VZERO T_2 // limbs for r
|
|
|
|
|
+ VZERO T_3
|
|
|
|
|
+ VZERO T_4
|
|
|
|
|
+ EXPACC2(T_0, T_2, T_3, T_4, T_1, T_5, T_7)
|
|
|
|
|
+
|
|
|
|
|
+ // T_2, T_3, T_4: [0, r]
|
|
|
|
|
+
|
|
|
|
|
+ // setup r*20
|
|
|
|
|
+ VLEIG $0, $0, T_0
|
|
|
|
|
+ VLEIG $1, $20, T_0 // T_0: [0, 20]
|
|
|
|
|
+ VZERO T_5
|
|
|
|
|
+ VZERO T_6
|
|
|
|
|
+ VMSLG T_0, T_3, T_5, T_5
|
|
|
|
|
+ VMSLG T_0, T_4, T_6, T_6
|
|
|
|
|
+
|
|
|
|
|
+ // store r for final block in GR
|
|
|
|
|
+ VLGVG $1, T_2, RSAVE_0 // c
|
|
|
|
|
+ VLGVG $1, T_3, RSAVE_1 // c
|
|
|
|
|
+ VLGVG $1, T_4, RSAVE_2 // c
|
|
|
|
|
+ VLGVG $1, T_5, R5SAVE_1 // c
|
|
|
|
|
+ VLGVG $1, T_6, R5SAVE_2 // c
|
|
|
|
|
+
|
|
|
|
|
+ // initialize h
|
|
|
|
|
+ VZERO H0_0
|
|
|
|
|
+ VZERO H1_0
|
|
|
|
|
+ VZERO H2_0
|
|
|
|
|
+ VZERO H0_1
|
|
|
|
|
+ VZERO H1_1
|
|
|
|
|
+ VZERO H2_1
|
|
|
|
|
+
|
|
|
|
|
+ // initialize pointer for reduce constants
|
|
|
|
|
+ MOVD $·reduce<>(SB), R12
|
|
|
|
|
+
|
|
|
|
|
+ // calculate r**2 and 20*(r**2)
|
|
|
|
|
+ VZERO R_0
|
|
|
|
|
+ VZERO R_1
|
|
|
|
|
+ VZERO R_2
|
|
|
|
|
+ SQUARE(T_2, T_3, T_4, T_6, R_0, R_1, R_2, T_1, T_5, T_7)
|
|
|
|
|
+ REDUCE2(R_0, R_1, R_2, M0, M1, M2, M3, M4, R5_1, R5_2, M5, T_1)
|
|
|
|
|
+ VZERO R5_1
|
|
|
|
|
+ VZERO R5_2
|
|
|
|
|
+ VMSLG T_0, R_1, R5_1, R5_1
|
|
|
|
|
+ VMSLG T_0, R_2, R5_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ // skip r**4 calculation if 3 blocks or less
|
|
|
|
|
+ CMPBLE R3, $48, b4
|
|
|
|
|
+
|
|
|
|
|
+ // calculate r**4 and 20*(r**4)
|
|
|
|
|
+ VZERO T_8
|
|
|
|
|
+ VZERO T_9
|
|
|
|
|
+ VZERO T_10
|
|
|
|
|
+ SQUARE(R_0, R_1, R_2, R5_2, T_8, T_9, T_10, T_1, T_5, T_7)
|
|
|
|
|
+ REDUCE2(T_8, T_9, T_10, M0, M1, M2, M3, M4, T_2, T_3, M5, T_1)
|
|
|
|
|
+ VZERO T_2
|
|
|
|
|
+ VZERO T_3
|
|
|
|
|
+ VMSLG T_0, T_9, T_2, T_2
|
|
|
|
|
+ VMSLG T_0, T_10, T_3, T_3
|
|
|
|
|
+
|
|
|
|
|
+ // put r**2 to the right and r**4 to the left of R_0, R_1, R_2
|
|
|
|
|
+ VSLDB $8, T_8, T_8, T_8
|
|
|
|
|
+ VSLDB $8, T_9, T_9, T_9
|
|
|
|
|
+ VSLDB $8, T_10, T_10, T_10
|
|
|
|
|
+ VSLDB $8, T_2, T_2, T_2
|
|
|
|
|
+ VSLDB $8, T_3, T_3, T_3
|
|
|
|
|
+
|
|
|
|
|
+ VO T_8, R_0, R_0
|
|
|
|
|
+ VO T_9, R_1, R_1
|
|
|
|
|
+ VO T_10, R_2, R_2
|
|
|
|
|
+ VO T_2, R5_1, R5_1
|
|
|
|
|
+ VO T_3, R5_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ CMPBLE R3, $80, load // less than or equal to 5 blocks in message
|
|
|
|
|
+
|
|
|
|
|
+ // 6(or 5+1) blocks
|
|
|
|
|
+ SUB $81, R3
|
|
|
|
|
+ VLM (R2), M0, M4
|
|
|
|
|
+ VLL R3, 80(R2), M5
|
|
|
|
|
+ ADD $1, R3
|
|
|
|
|
+ MOVBZ $1, R0
|
|
|
|
|
+ CMPBGE R3, $16, 2(PC)
|
|
|
|
|
+ VLVGB R3, R0, M5
|
|
|
|
|
+ MOVD $96(R2), R2
|
|
|
|
|
+ EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
|
|
|
|
+ EXPACC(M2, M3, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
|
|
|
|
+ VLEIB $2, $1, H2_0
|
|
|
|
|
+ VLEIB $2, $1, H2_1
|
|
|
|
|
+ VLEIB $10, $1, H2_0
|
|
|
|
|
+ VLEIB $10, $1, H2_1
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO T_4
|
|
|
|
|
+ VZERO T_10
|
|
|
|
|
+ EXPACC(M4, M5, M0, M1, M2, M3, T_4, T_10, T_0, T_1, T_2, T_3)
|
|
|
|
|
+ VLR T_4, M4
|
|
|
|
|
+ VLEIB $10, $1, M2
|
|
|
|
|
+ CMPBLT R3, $16, 2(PC)
|
|
|
|
|
+ VLEIB $10, $1, T_10
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9)
|
|
|
|
|
+ VMRHG V0, H0_1, H0_0
|
|
|
|
|
+ VMRHG V0, H1_1, H1_0
|
|
|
|
|
+ VMRHG V0, H2_1, H2_0
|
|
|
|
|
+ VMRLG V0, H0_1, H0_1
|
|
|
|
|
+ VMRLG V0, H1_1, H1_1
|
|
|
|
|
+ VMRLG V0, H2_1, H2_1
|
|
|
|
|
+
|
|
|
|
|
+ SUB $16, R3
|
|
|
|
|
+ CMPBLE R3, $0, square
|
|
|
|
|
+
|
|
|
|
|
+load:
|
|
|
|
|
+ // load EX0, EX1 and EX2
|
|
|
|
|
+ MOVD $·c<>(SB), R5
|
|
|
|
|
+ VLM (R5), EX0, EX2
|
|
|
|
|
+
|
|
|
|
|
+loop:
|
|
|
|
|
+ CMPBLE R3, $64, add // b4 // last 4 or less blocks left
|
|
|
|
|
+
|
|
|
|
|
+ // next 4 full blocks
|
|
|
|
|
+ VLM (R2), M2, M5
|
|
|
|
|
+ SUB $64, R3
|
|
|
|
|
+ MOVD $64(R2), R2
|
|
|
|
|
+ REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, T_0, T_1, T_3, T_4, T_5, T_2, T_7, T_8, T_9)
|
|
|
|
|
+
|
|
|
|
|
+ // expacc in-lined to create [m2, m3] limbs
|
|
|
|
|
+ VGBM $0x3f3f, T_0 // 44 bit clear mask
|
|
|
|
|
+ VGBM $0x1f1f, T_1 // 40 bit clear mask
|
|
|
|
|
+ VPERM M2, M3, EX0, T_3
|
|
|
|
|
+ VESRLG $4, T_0, T_0 // 44 bit clear mask ready
|
|
|
|
|
+ VPERM M2, M3, EX1, T_4
|
|
|
|
|
+ VPERM M2, M3, EX2, T_5
|
|
|
|
|
+ VN T_0, T_3, T_3
|
|
|
|
|
+ VESRLG $4, T_4, T_4
|
|
|
|
|
+ VN T_1, T_5, T_5
|
|
|
|
|
+ VN T_0, T_4, T_4
|
|
|
|
|
+ VMRHG H0_1, T_3, H0_0
|
|
|
|
|
+ VMRHG H1_1, T_4, H1_0
|
|
|
|
|
+ VMRHG H2_1, T_5, H2_0
|
|
|
|
|
+ VMRLG H0_1, T_3, H0_1
|
|
|
|
|
+ VMRLG H1_1, T_4, H1_1
|
|
|
|
|
+ VMRLG H2_1, T_5, H2_1
|
|
|
|
|
+ VLEIB $10, $1, H2_0
|
|
|
|
|
+ VLEIB $10, $1, H2_1
|
|
|
|
|
+ VPERM M4, M5, EX0, T_3
|
|
|
|
|
+ VPERM M4, M5, EX1, T_4
|
|
|
|
|
+ VPERM M4, M5, EX2, T_5
|
|
|
|
|
+ VN T_0, T_3, T_3
|
|
|
|
|
+ VESRLG $4, T_4, T_4
|
|
|
|
|
+ VN T_1, T_5, T_5
|
|
|
|
|
+ VN T_0, T_4, T_4
|
|
|
|
|
+ VMRHG V0, T_3, M0
|
|
|
|
|
+ VMRHG V0, T_4, M1
|
|
|
|
|
+ VMRHG V0, T_5, M2
|
|
|
|
|
+ VMRLG V0, T_3, M3
|
|
|
|
|
+ VMRLG V0, T_4, M4
|
|
|
|
|
+ VMRLG V0, T_5, M5
|
|
|
|
|
+ VLEIB $10, $1, M2
|
|
|
|
|
+ VLEIB $10, $1, M5
|
|
|
|
|
+
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ CMPBNE R3, $0, loop
|
|
|
|
|
+ REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
|
|
|
|
+ VMRHG V0, H0_1, H0_0
|
|
|
|
|
+ VMRHG V0, H1_1, H1_0
|
|
|
|
|
+ VMRHG V0, H2_1, H2_0
|
|
|
|
|
+ VMRLG V0, H0_1, H0_1
|
|
|
|
|
+ VMRLG V0, H1_1, H1_1
|
|
|
|
|
+ VMRLG V0, H2_1, H2_1
|
|
|
|
|
+
|
|
|
|
|
+ // load EX0, EX1, EX2
|
|
|
|
|
+ MOVD $·constants<>(SB), R5
|
|
|
|
|
+ VLM (R5), EX0, EX2
|
|
|
|
|
+
|
|
|
|
|
+ // sum vectors
|
|
|
|
|
+ VAQ H0_0, H0_1, H0_0
|
|
|
|
|
+ VAQ H1_0, H1_1, H1_0
|
|
|
|
|
+ VAQ H2_0, H2_1, H2_0
|
|
|
|
|
+
|
|
|
|
|
+ // h may be >= 2*(2**130-5) so we need to reduce it again
|
|
|
|
|
+ // M0...M4 are used as temps here
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
|
|
|
|
+
|
|
|
|
|
+next: // carry h1->h2
|
|
|
|
|
+ VLEIB $7, $0x28, T_1
|
|
|
|
|
+ VREPIB $4, T_2
|
|
|
|
|
+ VGBM $0x003F, T_3
|
|
|
|
|
+ VESRLG $4, T_3
|
|
|
|
|
+
|
|
|
|
|
+ // byte shift
|
|
|
|
|
+ VSRLB T_1, H1_0, T_4
|
|
|
|
|
+
|
|
|
|
|
+ // bit shift
|
|
|
|
|
+ VSRL T_2, T_4, T_4
|
|
|
|
|
+
|
|
|
|
|
+ // clear h1 carry bits
|
|
|
|
|
+ VN T_3, H1_0, H1_0
|
|
|
|
|
+
|
|
|
|
|
+ // add carry
|
|
|
|
|
+ VAQ T_4, H2_0, H2_0
|
|
|
|
|
+
|
|
|
|
|
+ // h is now < 2*(2**130-5)
|
|
|
|
|
+ // pack h into h1 (hi) and h0 (lo)
|
|
|
|
|
+ PACK(H0_0, H1_0, H2_0)
|
|
|
|
|
+
|
|
|
|
|
+ // if h > 2**130-5 then h -= 2**130-5
|
|
|
|
|
+ MOD(H0_0, H1_0, T_0, T_1, T_2)
|
|
|
|
|
+
|
|
|
|
|
+ // h += s
|
|
|
|
|
+ MOVD $·bswapMask<>(SB), R5
|
|
|
|
|
+ VL (R5), T_1
|
|
|
|
|
+ VL 16(R4), T_0
|
|
|
|
|
+ VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big)
|
|
|
|
|
+ VAQ T_0, H0_0, H0_0
|
|
|
|
|
+ VPERM H0_0, H0_0, T_1, H0_0 // reverse bytes (to little)
|
|
|
|
|
+ VST H0_0, (R1)
|
|
|
|
|
+ RET
|
|
|
|
|
+
|
|
|
|
|
+add:
|
|
|
|
|
+ // load EX0, EX1, EX2
|
|
|
|
|
+ MOVD $·constants<>(SB), R5
|
|
|
|
|
+ VLM (R5), EX0, EX2
|
|
|
|
|
+
|
|
|
|
|
+ REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
|
|
|
|
+ VMRHG V0, H0_1, H0_0
|
|
|
|
|
+ VMRHG V0, H1_1, H1_0
|
|
|
|
|
+ VMRHG V0, H2_1, H2_0
|
|
|
|
|
+ VMRLG V0, H0_1, H0_1
|
|
|
|
|
+ VMRLG V0, H1_1, H1_1
|
|
|
|
|
+ VMRLG V0, H2_1, H2_1
|
|
|
|
|
+ CMPBLE R3, $64, b4
|
|
|
|
|
+
|
|
|
|
|
+b4:
|
|
|
|
|
+ CMPBLE R3, $48, b3 // 3 blocks or less
|
|
|
|
|
+
|
|
|
|
|
+ // 4(3+1) blocks remaining
|
|
|
|
|
+ SUB $49, R3
|
|
|
|
|
+ VLM (R2), M0, M2
|
|
|
|
|
+ VLL R3, 48(R2), M3
|
|
|
|
|
+ ADD $1, R3
|
|
|
|
|
+ MOVBZ $1, R0
|
|
|
|
|
+ CMPBEQ R3, $16, 2(PC)
|
|
|
|
|
+ VLVGB R3, R0, M3
|
|
|
|
|
+ MOVD $64(R2), R2
|
|
|
|
|
+ EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
|
|
|
|
+ VLEIB $10, $1, H2_0
|
|
|
|
|
+ VLEIB $10, $1, H2_1
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+ VZERO T_4
|
|
|
|
|
+ VZERO T_10
|
|
|
|
|
+ EXPACC(M2, M3, M0, M1, M4, M5, T_4, T_10, T_0, T_1, T_2, T_3)
|
|
|
|
|
+ VLR T_4, M2
|
|
|
|
|
+ VLEIB $10, $1, M4
|
|
|
|
|
+ CMPBNE R3, $16, 2(PC)
|
|
|
|
|
+ VLEIB $10, $1, T_10
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M4, M5, M2, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
|
|
|
|
+ VMRHG V0, H0_1, H0_0
|
|
|
|
|
+ VMRHG V0, H1_1, H1_0
|
|
|
|
|
+ VMRHG V0, H2_1, H2_0
|
|
|
|
|
+ VMRLG V0, H0_1, H0_1
|
|
|
|
|
+ VMRLG V0, H1_1, H1_1
|
|
|
|
|
+ VMRLG V0, H2_1, H2_1
|
|
|
|
|
+ SUB $16, R3
|
|
|
|
|
+ CMPBLE R3, $0, square // this condition must always hold true!
|
|
|
|
|
+
|
|
|
|
|
+b3:
|
|
|
|
|
+ CMPBLE R3, $32, b2
|
|
|
|
|
+
|
|
|
|
|
+ // 3 blocks remaining
|
|
|
|
|
+
|
|
|
|
|
+ // setup [r²,r]
|
|
|
|
|
+ VSLDB $8, R_0, R_0, R_0
|
|
|
|
|
+ VSLDB $8, R_1, R_1, R_1
|
|
|
|
|
+ VSLDB $8, R_2, R_2, R_2
|
|
|
|
|
+ VSLDB $8, R5_1, R5_1, R5_1
|
|
|
|
|
+ VSLDB $8, R5_2, R5_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ VLVGG $1, RSAVE_0, R_0
|
|
|
|
|
+ VLVGG $1, RSAVE_1, R_1
|
|
|
|
|
+ VLVGG $1, RSAVE_2, R_2
|
|
|
|
|
+ VLVGG $1, R5SAVE_1, R5_1
|
|
|
|
|
+ VLVGG $1, R5SAVE_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ // setup [h0, h1]
|
|
|
|
|
+ VSLDB $8, H0_0, H0_0, H0_0
|
|
|
|
|
+ VSLDB $8, H1_0, H1_0, H1_0
|
|
|
|
|
+ VSLDB $8, H2_0, H2_0, H2_0
|
|
|
|
|
+ VO H0_1, H0_0, H0_0
|
|
|
|
|
+ VO H1_1, H1_0, H1_0
|
|
|
|
|
+ VO H2_1, H2_0, H2_0
|
|
|
|
|
+ VZERO H0_1
|
|
|
|
|
+ VZERO H1_1
|
|
|
|
|
+ VZERO H2_1
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+
|
|
|
|
|
+ // H*[r**2, r]
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, T_10, M5)
|
|
|
|
|
+
|
|
|
|
|
+ SUB $33, R3
|
|
|
|
|
+ VLM (R2), M0, M1
|
|
|
|
|
+ VLL R3, 32(R2), M2
|
|
|
|
|
+ ADD $1, R3
|
|
|
|
|
+ MOVBZ $1, R0
|
|
|
|
|
+ CMPBEQ R3, $16, 2(PC)
|
|
|
|
|
+ VLVGB R3, R0, M2
|
|
|
|
|
+
|
|
|
|
|
+ // H += m0
|
|
|
|
|
+ VZERO T_1
|
|
|
|
|
+ VZERO T_2
|
|
|
|
|
+ VZERO T_3
|
|
|
|
|
+ EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)
|
|
|
|
|
+ VLEIB $10, $1, T_3
|
|
|
|
|
+ VAG H0_0, T_1, H0_0
|
|
|
|
|
+ VAG H1_0, T_2, H1_0
|
|
|
|
|
+ VAG H2_0, T_3, H2_0
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+ VZERO T_10
|
|
|
|
|
+
|
|
|
|
|
+ // (H+m0)*r
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M3, M4, M5, V0, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_10, H0_1, H1_1, H2_1, T_9)
|
|
|
|
|
+
|
|
|
|
|
+ // H += m1
|
|
|
|
|
+ VZERO V0
|
|
|
|
|
+ VZERO T_1
|
|
|
|
|
+ VZERO T_2
|
|
|
|
|
+ VZERO T_3
|
|
|
|
|
+ EXPACC2(M1, T_1, T_2, T_3, T_4, T_5, T_6)
|
|
|
|
|
+ VLEIB $10, $1, T_3
|
|
|
|
|
+ VAQ H0_0, T_1, H0_0
|
|
|
|
|
+ VAQ H1_0, T_2, H1_0
|
|
|
|
|
+ VAQ H2_0, T_3, H2_0
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10)
|
|
|
|
|
+
|
|
|
|
|
+ // [H, m2] * [r**2, r]
|
|
|
|
|
+ EXPACC2(M2, H0_0, H1_0, H2_0, T_1, T_2, T_3)
|
|
|
|
|
+ CMPBNE R3, $16, 2(PC)
|
|
|
|
|
+ VLEIB $10, $1, H2_0
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, M5, T_10)
|
|
|
|
|
+ SUB $16, R3
|
|
|
|
|
+ CMPBLE R3, $0, next // this condition must always hold true!
|
|
|
|
|
+
|
|
|
|
|
+b2:
|
|
|
|
|
+ CMPBLE R3, $16, b1
|
|
|
|
|
+
|
|
|
|
|
+ // 2 blocks remaining
|
|
|
|
|
+
|
|
|
|
|
+ // setup [r²,r]
|
|
|
|
|
+ VSLDB $8, R_0, R_0, R_0
|
|
|
|
|
+ VSLDB $8, R_1, R_1, R_1
|
|
|
|
|
+ VSLDB $8, R_2, R_2, R_2
|
|
|
|
|
+ VSLDB $8, R5_1, R5_1, R5_1
|
|
|
|
|
+ VSLDB $8, R5_2, R5_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ VLVGG $1, RSAVE_0, R_0
|
|
|
|
|
+ VLVGG $1, RSAVE_1, R_1
|
|
|
|
|
+ VLVGG $1, RSAVE_2, R_2
|
|
|
|
|
+ VLVGG $1, R5SAVE_1, R5_1
|
|
|
|
|
+ VLVGG $1, R5SAVE_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ // setup [h0, h1]
|
|
|
|
|
+ VSLDB $8, H0_0, H0_0, H0_0
|
|
|
|
|
+ VSLDB $8, H1_0, H1_0, H1_0
|
|
|
|
|
+ VSLDB $8, H2_0, H2_0, H2_0
|
|
|
|
|
+ VO H0_1, H0_0, H0_0
|
|
|
|
|
+ VO H1_1, H1_0, H1_0
|
|
|
|
|
+ VO H2_1, H2_0, H2_0
|
|
|
|
|
+ VZERO H0_1
|
|
|
|
|
+ VZERO H1_1
|
|
|
|
|
+ VZERO H2_1
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+
|
|
|
|
|
+ // H*[r**2, r]
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9)
|
|
|
|
|
+ VMRHG V0, H0_1, H0_0
|
|
|
|
|
+ VMRHG V0, H1_1, H1_0
|
|
|
|
|
+ VMRHG V0, H2_1, H2_0
|
|
|
|
|
+ VMRLG V0, H0_1, H0_1
|
|
|
|
|
+ VMRLG V0, H1_1, H1_1
|
|
|
|
|
+ VMRLG V0, H2_1, H2_1
|
|
|
|
|
+
|
|
|
|
|
+ // move h to the left and 0s at the right
|
|
|
|
|
+ VSLDB $8, H0_0, H0_0, H0_0
|
|
|
|
|
+ VSLDB $8, H1_0, H1_0, H1_0
|
|
|
|
|
+ VSLDB $8, H2_0, H2_0, H2_0
|
|
|
|
|
+
|
|
|
|
|
+ // get message blocks and append 1 to start
|
|
|
|
|
+ SUB $17, R3
|
|
|
|
|
+ VL (R2), M0
|
|
|
|
|
+ VLL R3, 16(R2), M1
|
|
|
|
|
+ ADD $1, R3
|
|
|
|
|
+ MOVBZ $1, R0
|
|
|
|
|
+ CMPBEQ R3, $16, 2(PC)
|
|
|
|
|
+ VLVGB R3, R0, M1
|
|
|
|
|
+ VZERO T_6
|
|
|
|
|
+ VZERO T_7
|
|
|
|
|
+ VZERO T_8
|
|
|
|
|
+ EXPACC2(M0, T_6, T_7, T_8, T_1, T_2, T_3)
|
|
|
|
|
+ EXPACC2(M1, T_6, T_7, T_8, T_1, T_2, T_3)
|
|
|
|
|
+ VLEIB $2, $1, T_8
|
|
|
|
|
+ CMPBNE R3, $16, 2(PC)
|
|
|
|
|
+ VLEIB $10, $1, T_8
|
|
|
|
|
+
|
|
|
|
|
+ // add [m0, m1] to h
|
|
|
|
|
+ VAG H0_0, T_6, H0_0
|
|
|
|
|
+ VAG H1_0, T_7, H1_0
|
|
|
|
|
+ VAG H2_0, T_8, H2_0
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+ VZERO T_10
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+
|
|
|
|
|
+ // at this point R_0 .. R5_2 look like [r**2, r]
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M2, M3, M4, M5, T_10, M0, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M2, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10)
|
|
|
|
|
+ SUB $16, R3, R3
|
|
|
|
|
+ CMPBLE R3, $0, next
|
|
|
|
|
+
|
|
|
|
|
+b1:
|
|
|
|
|
+ CMPBLE R3, $0, next
|
|
|
|
|
+
|
|
|
|
|
+ // 1 block remaining
|
|
|
|
|
+
|
|
|
|
|
+ // setup [r²,r]
|
|
|
|
|
+ VSLDB $8, R_0, R_0, R_0
|
|
|
|
|
+ VSLDB $8, R_1, R_1, R_1
|
|
|
|
|
+ VSLDB $8, R_2, R_2, R_2
|
|
|
|
|
+ VSLDB $8, R5_1, R5_1, R5_1
|
|
|
|
|
+ VSLDB $8, R5_2, R5_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ VLVGG $1, RSAVE_0, R_0
|
|
|
|
|
+ VLVGG $1, RSAVE_1, R_1
|
|
|
|
|
+ VLVGG $1, RSAVE_2, R_2
|
|
|
|
|
+ VLVGG $1, R5SAVE_1, R5_1
|
|
|
|
|
+ VLVGG $1, R5SAVE_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ // setup [h0, h1]
|
|
|
|
|
+ VSLDB $8, H0_0, H0_0, H0_0
|
|
|
|
|
+ VSLDB $8, H1_0, H1_0, H1_0
|
|
|
|
|
+ VSLDB $8, H2_0, H2_0, H2_0
|
|
|
|
|
+ VO H0_1, H0_0, H0_0
|
|
|
|
|
+ VO H1_1, H1_0, H1_0
|
|
|
|
|
+ VO H2_1, H2_0, H2_0
|
|
|
|
|
+ VZERO H0_1
|
|
|
|
|
+ VZERO H1_1
|
|
|
|
|
+ VZERO H2_1
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+
|
|
|
|
|
+ // H*[r**2, r]
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
|
|
|
|
+
|
|
|
|
|
+ // set up [0, m0] limbs
|
|
|
|
|
+ SUB $1, R3
|
|
|
|
|
+ VLL R3, (R2), M0
|
|
|
|
|
+ ADD $1, R3
|
|
|
|
|
+ MOVBZ $1, R0
|
|
|
|
|
+ CMPBEQ R3, $16, 2(PC)
|
|
|
|
|
+ VLVGB R3, R0, M0
|
|
|
|
|
+ VZERO T_1
|
|
|
|
|
+ VZERO T_2
|
|
|
|
|
+ VZERO T_3
|
|
|
|
|
+ EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)// limbs: [0, m]
|
|
|
|
|
+ CMPBNE R3, $16, 2(PC)
|
|
|
|
|
+ VLEIB $10, $1, T_3
|
|
|
|
|
+
|
|
|
|
|
+ // h+m0
|
|
|
|
|
+ VAQ H0_0, T_1, H0_0
|
|
|
|
|
+ VAQ H1_0, T_2, H1_0
|
|
|
|
|
+ VAQ H2_0, T_3, H2_0
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
|
|
|
|
+
|
|
|
|
|
+ BR next
|
|
|
|
|
+
|
|
|
|
|
+square:
|
|
|
|
|
+ // setup [r²,r]
|
|
|
|
|
+ VSLDB $8, R_0, R_0, R_0
|
|
|
|
|
+ VSLDB $8, R_1, R_1, R_1
|
|
|
|
|
+ VSLDB $8, R_2, R_2, R_2
|
|
|
|
|
+ VSLDB $8, R5_1, R5_1, R5_1
|
|
|
|
|
+ VSLDB $8, R5_2, R5_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ VLVGG $1, RSAVE_0, R_0
|
|
|
|
|
+ VLVGG $1, RSAVE_1, R_1
|
|
|
|
|
+ VLVGG $1, RSAVE_2, R_2
|
|
|
|
|
+ VLVGG $1, R5SAVE_1, R5_1
|
|
|
|
|
+ VLVGG $1, R5SAVE_2, R5_2
|
|
|
|
|
+
|
|
|
|
|
+ // setup [h0, h1]
|
|
|
|
|
+ VSLDB $8, H0_0, H0_0, H0_0
|
|
|
|
|
+ VSLDB $8, H1_0, H1_0, H1_0
|
|
|
|
|
+ VSLDB $8, H2_0, H2_0, H2_0
|
|
|
|
|
+ VO H0_1, H0_0, H0_0
|
|
|
|
|
+ VO H1_1, H1_0, H1_0
|
|
|
|
|
+ VO H2_1, H2_0, H2_0
|
|
|
|
|
+ VZERO H0_1
|
|
|
|
|
+ VZERO H1_1
|
|
|
|
|
+ VZERO H2_1
|
|
|
|
|
+
|
|
|
|
|
+ VZERO M0
|
|
|
|
|
+ VZERO M1
|
|
|
|
|
+ VZERO M2
|
|
|
|
|
+ VZERO M3
|
|
|
|
|
+ VZERO M4
|
|
|
|
|
+ VZERO M5
|
|
|
|
|
+
|
|
|
|
|
+ // (h0*r**2) + (h1*r)
|
|
|
|
|
+ MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
|
|
|
|
+ REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
|
|
|
|
+ BR next
|
|
|
|
|
+
|
|
|
|
|
+TEXT ·hasVMSLFacility(SB), NOSPLIT, $24-1
|
|
|
|
|
+ MOVD $x-24(SP), R1
|
|
|
|
|
+ XC $24, 0(R1), 0(R1) // clear the storage
|
|
|
|
|
+ MOVD $2, R0 // R0 is the number of double words stored -1
|
|
|
|
|
+ WORD $0xB2B01000 // STFLE 0(R1)
|
|
|
|
|
+ XOR R0, R0 // reset the value of R0
|
|
|
|
|
+ MOVBZ z-8(SP), R1
|
|
|
|
|
+ AND $0x01, R1
|
|
|
|
|
+ BEQ novmsl
|
|
|
|
|
+
|
|
|
|
|
+vectorinstalled:
|
|
|
|
|
+ // check if the vector instruction has been enabled
|
|
|
|
|
+ VLEIB $0, $0xF, V16
|
|
|
|
|
+ VLGVB $0, V16, R1
|
|
|
|
|
+ CMPBNE R1, $0xF, novmsl
|
|
|
|
|
+ MOVB $1, ret+0(FP) // have vx
|
|
|
|
|
+ RET
|
|
|
|
|
+
|
|
|
|
|
+novmsl:
|
|
|
|
|
+ MOVB $0, ret+0(FP) // no vx
|
|
|
|
|
+ RET
|