• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moonbitlang / x / 950

21 Jul 2026 05:37AM UTC coverage: 84.986%. First build
950

Pull #280

github

web-flow
Merge 86831e10a into 8741d5cbb
Pull Request #280: Optimize ChaCha with target-aware SIMD

80 of 171 new or added lines in 3 files covered. (46.78%)

2649 of 3117 relevant lines covered (84.99%)

254.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.1
/crypto/chacha_simd.mbt
1
// Copyright 2025 International Digital Economy Academy
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
///|
16
#cfg(any(target="native", target="wasm"))
17
#inline
18
fn chacha4_enabled() -> Bool {
19
  true
24✔
20
}
21

22
///|
23
#cfg(not(any(target="native", target="wasm")))
24
#inline
25
fn chacha4_enabled() -> Bool {
NEW
26
  false
×
27
}
28

29
///|
30
#cfg(target="native")
31
#inline
32
fn chacha_quarter_round_v128(
33
  a : V128,
34
  b : V128,
35
  c : V128,
36
  d : V128,
37
) -> (V128, V128, V128, V128) {
NEW
38
  let a1 = @v128.i32x4_add(a, b)
×
NEW
39
  let d_xor_a = @v128.v128_xor(d, a1)
×
NEW
40
  let d1 = @v128.i8x16_shuffle(
×
41
    d_xor_a, d_xor_a, 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13,
42
  )
NEW
43
  let c1 = @v128.i32x4_add(c, d1)
×
NEW
44
  let b_xor_c = @v128.v128_xor(b, c1)
×
NEW
45
  let b1 = @v128.v128_or_(
×
NEW
46
    @v128.i32x4_shl(b_xor_c, 12),
×
NEW
47
    @v128.i32x4_shr_u(b_xor_c, 20),
×
48
  )
NEW
49
  let a2 = @v128.i32x4_add(a1, b1)
×
NEW
50
  let d_xor_a = @v128.v128_xor(d1, a2)
×
NEW
51
  let d2 = @v128.i8x16_shuffle(
×
52
    d_xor_a, d_xor_a, 3, 0, 1, 2, 7, 4, 5, 6, 11, 8, 9, 10, 15, 12, 13, 14,
53
  )
NEW
54
  let c2 = @v128.i32x4_add(c1, d2)
×
NEW
55
  let b_xor_c = @v128.v128_xor(b1, c2)
×
NEW
56
  let b2 = @v128.v128_or_(
×
NEW
57
    @v128.i32x4_shl(b_xor_c, 7),
×
NEW
58
    @v128.i32x4_shr_u(b_xor_c, 25),
×
59
  )
60
  (a2, b2, c2, d2)
61
}
62

63
///|
64
#cfg(target="native")
65
#inline
66
fn store_chacha4_word_group(
67
  output : FixedArray[Byte],
68
  byte_offset : Int,
69
  a : V128,
70
  b : V128,
71
  c : V128,
72
  d : V128,
73
) -> Unit {
NEW
74
  let ab_lo = @v128.i8x16_shuffle(
×
75
    a, b, 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23,
76
  )
NEW
77
  let ab_hi = @v128.i8x16_shuffle(
×
78
    a, b, 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31,
79
  )
NEW
80
  let cd_lo = @v128.i8x16_shuffle(
×
81
    c, d, 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23,
82
  )
NEW
83
  let cd_hi = @v128.i8x16_shuffle(
×
84
    c, d, 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31,
85
  )
NEW
86
  @v128.v128_store(
×
87
    output,
88
    byte_offset,
NEW
89
    @v128.i8x16_shuffle(
×
90
      ab_lo, cd_lo, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23,
91
    ),
92
  )
NEW
93
  @v128.v128_store(
×
94
    output,
95
    byte_offset + 64,
NEW
96
    @v128.i8x16_shuffle(
×
97
      ab_lo, cd_lo, 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31,
98
    ),
99
  )
NEW
100
  @v128.v128_store(
×
101
    output,
102
    byte_offset + 128,
NEW
103
    @v128.i8x16_shuffle(
×
104
      ab_hi, cd_hi, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23,
105
    ),
106
  )
NEW
107
  @v128.v128_store(
×
108
    output,
109
    byte_offset + 192,
NEW
110
    @v128.i8x16_shuffle(
×
111
      ab_hi, cd_hi, 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31,
112
    ),
113
  )
114
}
115

116
///|
117
#cfg(target="native")
118
fn chacha4BlockBytes(
119
  key : FixedArray[UInt],
120
  count : UInt,
121
  nonce : FixedArray[UInt],
122
  round : UInt,
123
  _scratch_words : FixedArray[UInt],
124
  _scratch_bytes : FixedArray[Byte],
125
  output : FixedArray[Byte],
126
) -> Unit {
NEW
127
  guard key.length() == 8
×
NEW
128
  guard nonce.length() == 3
×
NEW
129
  guard output.length() >= 256
×
NEW
130
  let initial0 = @v128.i32x4_splat(0X61707865)
×
NEW
131
  let initial1 = @v128.i32x4_splat(0X3320646e)
×
NEW
132
  let initial2 = @v128.i32x4_splat(0X79622d32)
×
NEW
133
  let initial3 = @v128.i32x4_splat(0X6b206574)
×
NEW
134
  let initial4 = @v128.i32x4_splat(key[0])
×
NEW
135
  let initial5 = @v128.i32x4_splat(key[1])
×
NEW
136
  let initial6 = @v128.i32x4_splat(key[2])
×
NEW
137
  let initial7 = @v128.i32x4_splat(key[3])
×
NEW
138
  let initial8 = @v128.i32x4_splat(key[4])
×
NEW
139
  let initial9 = @v128.i32x4_splat(key[5])
×
NEW
140
  let initial10 = @v128.i32x4_splat(key[6])
×
NEW
141
  let initial11 = @v128.i32x4_splat(key[7])
×
NEW
142
  let initial12 = @v128.i32x4_const(count, count + 1, count + 2, count + 3)
×
NEW
143
  let initial13 = @v128.i32x4_splat(nonce[0])
×
NEW
144
  let initial14 = @v128.i32x4_splat(nonce[1])
×
NEW
145
  let initial15 = @v128.i32x4_splat(nonce[2])
×
146
  let mut x0 = initial0
147
  let mut x1 = initial1
148
  let mut x2 = initial2
149
  let mut x3 = initial3
150
  let mut x4 = initial4
151
  let mut x5 = initial5
152
  let mut x6 = initial6
153
  let mut x7 = initial7
154
  let mut x8 = initial8
155
  let mut x9 = initial9
156
  let mut x10 = initial10
157
  let mut x11 = initial11
158
  let mut x12 = initial12
159
  let mut x13 = initial13
160
  let mut x14 = initial14
161
  let mut x15 = initial15
162
  for _ in 0U..<round {
NEW
163
    {
×
NEW
164
      let (a, b, c, d) = chacha_quarter_round_v128(x0, x4, x8, x12)
×
165
      x0 = a
166
      x4 = b
167
      x8 = c
168
      x12 = d
169
    }
170
    {
NEW
171
      let (a, b, c, d) = chacha_quarter_round_v128(x1, x5, x9, x13)
×
172
      x1 = a
173
      x5 = b
174
      x9 = c
175
      x13 = d
176
    }
177
    {
NEW
178
      let (a, b, c, d) = chacha_quarter_round_v128(x2, x6, x10, x14)
×
179
      x2 = a
180
      x6 = b
181
      x10 = c
182
      x14 = d
183
    }
184
    {
NEW
185
      let (a, b, c, d) = chacha_quarter_round_v128(x3, x7, x11, x15)
×
186
      x3 = a
187
      x7 = b
188
      x11 = c
189
      x15 = d
190
    }
191
    {
NEW
192
      let (a, b, c, d) = chacha_quarter_round_v128(x0, x5, x10, x15)
×
193
      x0 = a
194
      x5 = b
195
      x10 = c
196
      x15 = d
197
    }
198
    {
NEW
199
      let (a, b, c, d) = chacha_quarter_round_v128(x1, x6, x11, x12)
×
200
      x1 = a
201
      x6 = b
202
      x11 = c
203
      x12 = d
204
    }
205
    {
NEW
206
      let (a, b, c, d) = chacha_quarter_round_v128(x2, x7, x8, x13)
×
207
      x2 = a
208
      x7 = b
209
      x8 = c
210
      x13 = d
211
    }
NEW
212
    let (a, b, c, d) = chacha_quarter_round_v128(x3, x4, x9, x14)
×
213
    x3 = a
214
    x4 = b
215
    x9 = c
216
    x14 = d
217
  }
NEW
218
  x0 = @v128.i32x4_add(x0, initial0)
×
NEW
219
  x1 = @v128.i32x4_add(x1, initial1)
×
NEW
220
  x2 = @v128.i32x4_add(x2, initial2)
×
NEW
221
  x3 = @v128.i32x4_add(x3, initial3)
×
NEW
222
  x4 = @v128.i32x4_add(x4, initial4)
×
NEW
223
  x5 = @v128.i32x4_add(x5, initial5)
×
NEW
224
  x6 = @v128.i32x4_add(x6, initial6)
×
NEW
225
  x7 = @v128.i32x4_add(x7, initial7)
×
NEW
226
  x8 = @v128.i32x4_add(x8, initial8)
×
NEW
227
  x9 = @v128.i32x4_add(x9, initial9)
×
NEW
228
  x10 = @v128.i32x4_add(x10, initial10)
×
NEW
229
  x11 = @v128.i32x4_add(x11, initial11)
×
NEW
230
  x12 = @v128.i32x4_add(x12, initial12)
×
NEW
231
  x13 = @v128.i32x4_add(x13, initial13)
×
NEW
232
  x14 = @v128.i32x4_add(x14, initial14)
×
NEW
233
  x15 = @v128.i32x4_add(x15, initial15)
×
NEW
234
  store_chacha4_word_group(output, 0, x0, x1, x2, x3)
×
NEW
235
  store_chacha4_word_group(output, 16, x4, x5, x6, x7)
×
NEW
236
  store_chacha4_word_group(output, 32, x8, x9, x10, x11)
×
NEW
237
  store_chacha4_word_group(output, 48, x12, x13, x14, x15)
×
238
}
239

240
///|
241
#cfg(not(target="native"))
242
fn chacha4BlockBytes(
243
  key : FixedArray[UInt],
244
  count : UInt,
245
  nonce : FixedArray[UInt],
246
  round : UInt,
247
  scratch_words : FixedArray[UInt],
248
  scratch_bytes : FixedArray[Byte],
249
  output : FixedArray[Byte],
250
) -> Unit {
251
  for block in 0..<4 {
4✔
252
    chachaBlockBytes(
16✔
253
      key,
254
      count + block.reinterpret_as_uint(),
16✔
255
      nonce,
256
      round,
257
      scratch_words,
258
      scratch_bytes,
259
    )
260
    scratch_bytes.blit_to(output, len=64, dst_offset=block * 64)
16✔
261
  }
262
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc