1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build gc && !purego
6
7#include "textflag.h"
8
9// This was ported from the amd64 implementation.
10
11#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \
12 MOVD (msg), t0; \
13 MOVD 8(msg), t1; \
14 MOVD $1, t2; \
15 ADDC t0, h0, h0; \
16 ADDE t1, h1, h1; \
17 ADDE t2, h2; \
18 ADD $16, msg
19
20#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
21 MULLD r0, h0, t0; \
22 MULHDU r0, h0, t1; \
23 MULLD r0, h1, t4; \
24 MULHDU r0, h1, t5; \
25 ADDC t4, t1, t1; \
26 MULLD r0, h2, t2; \
27 MULHDU r1, h0, t4; \
28 MULLD r1, h0, h0; \
29 ADDE t5, t2, t2; \
30 ADDC h0, t1, t1; \
31 MULLD h2, r1, t3; \
32 ADDZE t4, h0; \
33 MULHDU r1, h1, t5; \
34 MULLD r1, h1, t4; \
35 ADDC t4, t2, t2; \
36 ADDE t5, t3, t3; \
37 ADDC h0, t2, t2; \
38 MOVD $-4, t4; \
39 ADDZE t3; \
40 RLDICL $0, t2, $62, h2; \
41 AND t2, t4, h0; \
42 ADDC t0, h0, h0; \
43 ADDE t3, t1, h1; \
44 SLD $62, t3, t4; \
45 SRD $2, t2; \
46 ADDZE h2; \
47 OR t4, t2, t2; \
48 SRD $2, t3; \
49 ADDC t2, h0, h0; \
50 ADDE t3, h1, h1; \
51 ADDZE h2
52
53DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
54DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
55GLOBL ·poly1305Mask<>(SB), RODATA, $16
56
57// func update(state *[7]uint64, msg []byte)
58TEXT ·update(SB), $0-32
59 MOVD state+0(FP), R3
60 MOVD msg_base+8(FP), R4
61 MOVD msg_len+16(FP), R5
62
63 MOVD 0(R3), R8 // h0
64 MOVD 8(R3), R9 // h1
65 MOVD 16(R3), R10 // h2
66 MOVD 24(R3), R11 // r0
67 MOVD 32(R3), R12 // r1
68
69 CMP R5, $16
70 BLT bytes_between_0_and_15
71
72loop:
73 POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)
74
75 PCALIGN $16
76multiply:
77 POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)
78 ADD $-16, R5
79 CMP R5, $16
80 BGE loop
81
82bytes_between_0_and_15:
83 CMP R5, $0
84 BEQ done
85 MOVD $0, R16 // h0
86 MOVD $0, R17 // h1
87
88flush_buffer:
89 CMP R5, $8
90 BLE just1
91
92 MOVD $8, R21
93 SUB R21, R5, R21
94
95 // Greater than 8 -- load the rightmost remaining bytes in msg
96 // and put into R17 (h1)
97 MOVD (R4)(R21), R17
98 MOVD $16, R22
99
100 // Find the offset to those bytes
101 SUB R5, R22, R22
102 SLD $3, R22
103
104 // Shift to get only the bytes in msg
105 SRD R22, R17, R17
106
107 // Put 1 at high end
108 MOVD $1, R23
109 SLD $3, R21
110 SLD R21, R23, R23
111 OR R23, R17, R17
112
113 // Remainder is 8
114 MOVD $8, R5
115
116just1:
117 CMP R5, $8
118 BLT less8
119
120 // Exactly 8
121 MOVD (R4), R16
122
123 CMP R17, $0
124
125 // Check if we've already set R17; if not
126 // set 1 to indicate end of msg.
127 BNE carry
128 MOVD $1, R17
129 BR carry
130
131less8:
132 MOVD $0, R16 // h0
133 MOVD $0, R22 // shift count
134 CMP R5, $4
135 BLT less4
136 MOVWZ (R4), R16
137 ADD $4, R4
138 ADD $-4, R5
139 MOVD $32, R22
140
141less4:
142 CMP R5, $2
143 BLT less2
144 MOVHZ (R4), R21
145 SLD R22, R21, R21
146 OR R16, R21, R16
147 ADD $16, R22
148 ADD $-2, R5
149 ADD $2, R4
150
151less2:
152 CMP R5, $0
153 BEQ insert1
154 MOVBZ (R4), R21
155 SLD R22, R21, R21
156 OR R16, R21, R16
157 ADD $8, R22
158
159insert1:
160 // Insert 1 at end of msg
161 MOVD $1, R21
162 SLD R22, R21, R21
163 OR R16, R21, R16
164
165carry:
166 // Add new values to h0, h1, h2
167 ADDC R16, R8
168 ADDE R17, R9
169 ADDZE R10, R10
170 MOVD $16, R5
171 ADD R5, R4
172 BR multiply
173
174done:
175 // Save h0, h1, h2 in state
176 MOVD R8, 0(R3)
177 MOVD R9, 8(R3)
178 MOVD R10, 16(R3)
179 RET
View as plain text