|
|
@@ -0,0 +1,247 @@
|
|
|
+// Copyright 2019 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 ppc64le,!gccgo,!appengine
|
|
|
+
|
|
|
+#include "textflag.h"
|
|
|
+
|
|
|
+// This was ported from the amd64 implementation.
|
|
|
+
|
|
|
+#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \
|
|
|
+ MOVD (msg), t0; \
|
|
|
+ MOVD 8(msg), t1; \
|
|
|
+ MOVD $1, t2; \
|
|
|
+ ADDC t0, h0, h0; \
|
|
|
+ ADDE t1, h1, h1; \
|
|
|
+ ADDE t2, h2; \
|
|
|
+ ADD $16, msg
|
|
|
+
|
|
|
+#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
|
|
|
+ MULLD r0, h0, t0; \
|
|
|
+ MULLD r0, h1, t4; \
|
|
|
+ MULHDU r0, h0, t1; \
|
|
|
+ MULHDU r0, h1, t5; \
|
|
|
+ ADDC t4, t1, t1; \
|
|
|
+ MULLD r0, h2, t2; \
|
|
|
+ ADDZE t5; \
|
|
|
+ MULHDU r1, h0, t4; \
|
|
|
+ MULLD r1, h0, h0; \
|
|
|
+ ADD t5, t2, t2; \
|
|
|
+ ADDC h0, t1, t1; \
|
|
|
+ MULLD h2, r1, t3; \
|
|
|
+ ADDZE t4, h0; \
|
|
|
+ MULHDU r1, h1, t5; \
|
|
|
+ MULLD r1, h1, t4; \
|
|
|
+ ADDC t4, t2, t2; \
|
|
|
+ ADDE t5, t3, t3; \
|
|
|
+ ADDC h0, t2, t2; \
|
|
|
+ MOVD $-4, t4; \
|
|
|
+ MOVD t0, h0; \
|
|
|
+ MOVD t1, h1; \
|
|
|
+ ADDZE t3; \
|
|
|
+ ANDCC $3, t2, h2; \
|
|
|
+ AND t2, t4, t0; \
|
|
|
+ ADDC t0, h0, h0; \
|
|
|
+ ADDE t3, h1, h1; \
|
|
|
+ SLD $62, t3, t4; \
|
|
|
+ SRD $2, t2; \
|
|
|
+ ADDZE h2; \
|
|
|
+ OR t4, t2, t2; \
|
|
|
+ SRD $2, t3; \
|
|
|
+ ADDC t2, h0, h0; \
|
|
|
+ ADDE t3, h1, h1; \
|
|
|
+ ADDZE h2
|
|
|
+
|
|
|
+DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
|
|
|
+DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
|
|
+GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
|
|
+
|
|
|
+// func update(state *[7]uint64, msg []byte)
|
|
|
+
|
|
|
+TEXT ·update(SB), $0-32
|
|
|
+ MOVD state+0(FP), R3
|
|
|
+ MOVD msg_base+8(FP), R4
|
|
|
+ MOVD msg_len+16(FP), R5
|
|
|
+
|
|
|
+ MOVD 0(R3), R8 // h0
|
|
|
+ MOVD 8(R3), R9 // h1
|
|
|
+ MOVD 16(R3), R10 // h2
|
|
|
+ MOVD 24(R3), R11 // r0
|
|
|
+ MOVD 32(R3), R12 // r1
|
|
|
+
|
|
|
+ CMP R5, $16
|
|
|
+ BLT bytes_between_0_and_15
|
|
|
+
|
|
|
+loop:
|
|
|
+ POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)
|
|
|
+
|
|
|
+multiply:
|
|
|
+ POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)
|
|
|
+ ADD $-16, R5
|
|
|
+ CMP R5, $16
|
|
|
+ BGE loop
|
|
|
+
|
|
|
+bytes_between_0_and_15:
|
|
|
+ CMP $0, R5
|
|
|
+ BEQ done
|
|
|
+ MOVD $0, R16 // h0
|
|
|
+ MOVD $0, R17 // h1
|
|
|
+
|
|
|
+flush_buffer:
|
|
|
+ CMP R5, $8
|
|
|
+ BLE just1
|
|
|
+
|
|
|
+ MOVD $8, R21
|
|
|
+ SUB R21, R5, R21
|
|
|
+
|
|
|
+ // Greater than 8 -- load the rightmost remaining bytes in msg
|
|
|
+ // and put into R17 (h1)
|
|
|
+ MOVD (R4)(R21), R17
|
|
|
+ MOVD $16, R22
|
|
|
+
|
|
|
+ // Find the offset to those bytes
|
|
|
+ SUB R5, R22, R22
|
|
|
+ SLD $3, R22
|
|
|
+
|
|
|
+ // Shift to get only the bytes in msg
|
|
|
+ SRD R22, R17, R17
|
|
|
+
|
|
|
+ // Put 1 at high end
|
|
|
+ MOVD $1, R23
|
|
|
+ SLD $3, R21
|
|
|
+ SLD R21, R23, R23
|
|
|
+ OR R23, R17, R17
|
|
|
+
|
|
|
+ // Remainder is 8
|
|
|
+ MOVD $8, R5
|
|
|
+
|
|
|
+just1:
|
|
|
+ CMP R5, $8
|
|
|
+ BLT less8
|
|
|
+
|
|
|
+ // Exactly 8
|
|
|
+ MOVD (R4), R16
|
|
|
+
|
|
|
+ CMP $0, R17
|
|
|
+
|
|
|
+ // Check if we've already set R17; if not
|
|
|
+ // set 1 to indicate end of msg.
|
|
|
+ BNE carry
|
|
|
+ MOVD $1, R17
|
|
|
+ BR carry
|
|
|
+
|
|
|
+less8:
|
|
|
+ MOVD $0, R16 // h0
|
|
|
+ MOVD $0, R22 // shift count
|
|
|
+ CMP R5, $4
|
|
|
+ BLT less4
|
|
|
+ MOVWZ (R4), R16
|
|
|
+ ADD $4, R4
|
|
|
+ ADD $-4, R5
|
|
|
+ MOVD $32, R22
|
|
|
+
|
|
|
+less4:
|
|
|
+ CMP R5, $2
|
|
|
+ BLT less2
|
|
|
+ MOVHZ (R4), R21
|
|
|
+ SLD R22, R21, R21
|
|
|
+ OR R16, R21, R16
|
|
|
+ ADD $16, R22
|
|
|
+ ADD $-2, R5
|
|
|
+ ADD $2, R4
|
|
|
+
|
|
|
+less2:
|
|
|
+ CMP $0, R5
|
|
|
+ BEQ insert1
|
|
|
+ MOVBZ (R4), R21
|
|
|
+ SLD R22, R21, R21
|
|
|
+ OR R16, R21, R16
|
|
|
+ ADD $8, R22
|
|
|
+
|
|
|
+insert1:
|
|
|
+ // Insert 1 at end of msg
|
|
|
+ MOVD $1, R21
|
|
|
+ SLD R22, R21, R21
|
|
|
+ OR R16, R21, R16
|
|
|
+
|
|
|
+carry:
|
|
|
+ // Add new values to h0, h1, h2
|
|
|
+ ADDC R16, R8
|
|
|
+ ADDE R17, R9
|
|
|
+ ADDE $0, R10
|
|
|
+ MOVD $16, R5
|
|
|
+ ADD R5, R4
|
|
|
+ BR multiply
|
|
|
+
|
|
|
+done:
|
|
|
+ // Save h0, h1, h2 in state
|
|
|
+ MOVD R8, 0(R3)
|
|
|
+ MOVD R9, 8(R3)
|
|
|
+ MOVD R10, 16(R3)
|
|
|
+ RET
|
|
|
+
|
|
|
+// func initialize(state *[7]uint64, key *[32]byte)
|
|
|
+TEXT ·initialize(SB), $0-16
|
|
|
+ MOVD state+0(FP), R3
|
|
|
+ MOVD key+8(FP), R4
|
|
|
+
|
|
|
+ // state[0...7] is initialized with zero
|
|
|
+ // Load key
|
|
|
+ MOVD 0(R4), R5
|
|
|
+ MOVD 8(R4), R6
|
|
|
+ MOVD 16(R4), R7
|
|
|
+ MOVD 24(R4), R8
|
|
|
+
|
|
|
+ // Address of key mask
|
|
|
+ MOVD $·poly1305Mask<>(SB), R9
|
|
|
+
|
|
|
+ // Save original key in state
|
|
|
+ MOVD R7, 40(R3)
|
|
|
+ MOVD R8, 48(R3)
|
|
|
+
|
|
|
+ // Get mask
|
|
|
+ MOVD (R9), R7
|
|
|
+ MOVD 8(R9), R8
|
|
|
+
|
|
|
+ // And with key
|
|
|
+ AND R5, R7, R5
|
|
|
+ AND R6, R8, R6
|
|
|
+
|
|
|
+ // Save masked key in state
|
|
|
+ MOVD R5, 24(R3)
|
|
|
+ MOVD R6, 32(R3)
|
|
|
+ RET
|
|
|
+
|
|
|
+// func finalize(tag *[TagSize]byte, state *[7]uint64)
|
|
|
+TEXT ·finalize(SB), $0-16
|
|
|
+ MOVD tag+0(FP), R3
|
|
|
+ MOVD state+8(FP), R4
|
|
|
+
|
|
|
+ // Get h0, h1, h2 from state
|
|
|
+ MOVD 0(R4), R5
|
|
|
+ MOVD 8(R4), R6
|
|
|
+ MOVD 16(R4), R7
|
|
|
+
|
|
|
+ // Save h0, h1
|
|
|
+ MOVD R5, R8
|
|
|
+ MOVD R6, R9
|
|
|
+ MOVD $3, R20
|
|
|
+ MOVD $-1, R21
|
|
|
+ SUBC $-5, R5
|
|
|
+ SUBE R21, R6
|
|
|
+ SUBE R20, R7
|
|
|
+ MOVD $0, R21
|
|
|
+ SUBZE R21
|
|
|
+
|
|
|
+ // Check for carry
|
|
|
+ CMP $0, R21
|
|
|
+ ISEL $2, R5, R8, R5
|
|
|
+ ISEL $2, R6, R9, R6
|
|
|
+ MOVD 40(R4), R8
|
|
|
+ MOVD 48(R4), R9
|
|
|
+ ADDC R8, R5
|
|
|
+ ADDE R9, R6
|
|
|
+ MOVD R5, 0(R3)
|
|
|
+ MOVD R6, 8(R3)
|
|
|
+ RET
|