Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/nacl/bindings/crypto_core.py: 28%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

74 statements  

1# Copyright 2018 Donald Stufft and individual contributors 

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 

16from nacl import exceptions as exc 

17from nacl._sodium import ffi, lib 

18from nacl.exceptions import ensure 

19 

20 

21has_crypto_core_ed25519 = bool(lib.PYNACL_HAS_CRYPTO_CORE_ED25519) 

22 

23crypto_core_ed25519_BYTES = 0 

24crypto_core_ed25519_SCALARBYTES = 0 

25crypto_core_ed25519_NONREDUCEDSCALARBYTES = 0 

26 

27if has_crypto_core_ed25519: 

28 crypto_core_ed25519_BYTES = lib.crypto_core_ed25519_bytes() 

29 crypto_core_ed25519_SCALARBYTES = lib.crypto_core_ed25519_scalarbytes() 

30 crypto_core_ed25519_NONREDUCEDSCALARBYTES = ( 

31 lib.crypto_core_ed25519_nonreducedscalarbytes() 

32 ) 

33 

34 

35def crypto_core_ed25519_is_valid_point(p: bytes) -> bool: 

36 """ 

37 Check if ``p`` represents a point on the edwards25519 curve, in canonical 

38 form, on the main subgroup, and that the point doesn't have a small order. 

39 

40 :param p: a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

41 representing a point on the edwards25519 curve 

42 :type p: bytes 

43 :return: point validity 

44 :rtype: bool 

45 :raises nacl.exceptions.UnavailableError: If called when using a 

46 minimal build of libsodium. 

47 """ 

48 ensure( 

49 has_crypto_core_ed25519, 

50 "Not available in minimal build", 

51 raising=exc.UnavailableError, 

52 ) 

53 

54 ensure( 

55 isinstance(p, bytes) and len(p) == crypto_core_ed25519_BYTES, 

56 "Point must be a crypto_core_ed25519_BYTES long bytes sequence", 

57 raising=exc.TypeError, 

58 ) 

59 

60 rc = lib.crypto_core_ed25519_is_valid_point(p) 

61 return rc == 1 

62 

63 

64def crypto_core_ed25519_add(p: bytes, q: bytes) -> bytes: 

65 """ 

66 Add two points on the edwards25519 curve. 

67 

68 :param p: a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

69 representing a point on the edwards25519 curve 

70 :type p: bytes 

71 :param q: a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

72 representing a point on the edwards25519 curve 

73 :type q: bytes 

74 :return: a point on the edwards25519 curve represented as 

75 a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

76 :rtype: bytes 

77 :raises nacl.exceptions.UnavailableError: If called when using a 

78 minimal build of libsodium. 

79 """ 

80 ensure( 

81 has_crypto_core_ed25519, 

82 "Not available in minimal build", 

83 raising=exc.UnavailableError, 

84 ) 

85 

86 ensure( 

87 isinstance(p, bytes) 

88 and isinstance(q, bytes) 

89 and len(p) == crypto_core_ed25519_BYTES 

90 and len(q) == crypto_core_ed25519_BYTES, 

91 "Each point must be a {} long bytes sequence".format( 

92 "crypto_core_ed25519_BYTES" 

93 ), 

94 raising=exc.TypeError, 

95 ) 

96 

97 r = ffi.new("unsigned char[]", crypto_core_ed25519_BYTES) 

98 

99 rc = lib.crypto_core_ed25519_add(r, p, q) 

100 ensure(rc == 0, "Unexpected library error", raising=exc.RuntimeError) 

101 

102 return ffi.buffer(r, crypto_core_ed25519_BYTES)[:] 

103 

104 

105def crypto_core_ed25519_sub(p: bytes, q: bytes) -> bytes: 

106 """ 

107 Subtract a point from another on the edwards25519 curve. 

108 

109 :param p: a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

110 representing a point on the edwards25519 curve 

111 :type p: bytes 

112 :param q: a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

113 representing a point on the edwards25519 curve 

114 :type q: bytes 

115 :return: a point on the edwards25519 curve represented as 

116 a :py:data:`.crypto_core_ed25519_BYTES` long bytes sequence 

117 :rtype: bytes 

118 :raises nacl.exceptions.UnavailableError: If called when using a 

119 minimal build of libsodium. 

120 """ 

121 ensure( 

122 has_crypto_core_ed25519, 

123 "Not available in minimal build", 

124 raising=exc.UnavailableError, 

125 ) 

126 

127 ensure( 

128 isinstance(p, bytes) 

129 and isinstance(q, bytes) 

130 and len(p) == crypto_core_ed25519_BYTES 

131 and len(q) == crypto_core_ed25519_BYTES, 

132 "Each point must be a {} long bytes sequence".format( 

133 "crypto_core_ed25519_BYTES" 

134 ), 

135 raising=exc.TypeError, 

136 ) 

137 

138 r = ffi.new("unsigned char[]", crypto_core_ed25519_BYTES) 

139 

140 rc = lib.crypto_core_ed25519_sub(r, p, q) 

141 ensure(rc == 0, "Unexpected library error", raising=exc.RuntimeError) 

142 

143 return ffi.buffer(r, crypto_core_ed25519_BYTES)[:] 

144 

145 

146def crypto_core_ed25519_scalar_invert(s: bytes) -> bytes: 

147 """ 

148 Return the multiplicative inverse of integer ``s`` modulo ``L``, 

149 i.e an integer ``i`` such that ``s * i = 1 (mod L)``, where ``L`` 

150 is the order of the main subgroup. 

151 

152 Raises a ``exc.RuntimeError`` if ``s`` is the integer zero. 

153 

154 :param s: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

155 long bytes sequence representing an integer 

156 :type s: bytes 

157 :return: an integer represented as a 

158 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

159 :rtype: bytes 

160 :raises nacl.exceptions.UnavailableError: If called when using a 

161 minimal build of libsodium. 

162 """ 

163 ensure( 

164 has_crypto_core_ed25519, 

165 "Not available in minimal build", 

166 raising=exc.UnavailableError, 

167 ) 

168 

169 ensure( 

170 isinstance(s, bytes) and len(s) == crypto_core_ed25519_SCALARBYTES, 

171 "Integer s must be a {} long bytes sequence".format( 

172 "crypto_core_ed25519_SCALARBYTES" 

173 ), 

174 raising=exc.TypeError, 

175 ) 

176 

177 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

178 

179 rc = lib.crypto_core_ed25519_scalar_invert(r, s) 

180 ensure(rc == 0, "Unexpected library error", raising=exc.RuntimeError) 

181 

182 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:] 

183 

184 

185def crypto_core_ed25519_scalar_negate(s: bytes) -> bytes: 

186 """ 

187 Return the integer ``n`` such that ``s + n = 0 (mod L)``, where ``L`` 

188 is the order of the main subgroup. 

189 

190 :param s: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

191 long bytes sequence representing an integer 

192 :type s: bytes 

193 :return: an integer represented as a 

194 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

195 :rtype: bytes 

196 :raises nacl.exceptions.UnavailableError: If called when using a 

197 minimal build of libsodium. 

198 """ 

199 ensure( 

200 has_crypto_core_ed25519, 

201 "Not available in minimal build", 

202 raising=exc.UnavailableError, 

203 ) 

204 

205 ensure( 

206 isinstance(s, bytes) and len(s) == crypto_core_ed25519_SCALARBYTES, 

207 "Integer s must be a {} long bytes sequence".format( 

208 "crypto_core_ed25519_SCALARBYTES" 

209 ), 

210 raising=exc.TypeError, 

211 ) 

212 

213 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

214 

215 lib.crypto_core_ed25519_scalar_negate(r, s) 

216 

217 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:] 

218 

219 

220def crypto_core_ed25519_scalar_complement(s: bytes) -> bytes: 

221 """ 

222 Return the complement of integer ``s`` modulo ``L``, i.e. an integer 

223 ``c`` such that ``s + c = 1 (mod L)``, where ``L`` is the order of 

224 the main subgroup. 

225 

226 :param s: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

227 long bytes sequence representing an integer 

228 :type s: bytes 

229 :return: an integer represented as a 

230 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

231 :rtype: bytes 

232 :raises nacl.exceptions.UnavailableError: If called when using a 

233 minimal build of libsodium. 

234 """ 

235 ensure( 

236 has_crypto_core_ed25519, 

237 "Not available in minimal build", 

238 raising=exc.UnavailableError, 

239 ) 

240 

241 ensure( 

242 isinstance(s, bytes) and len(s) == crypto_core_ed25519_SCALARBYTES, 

243 "Integer s must be a {} long bytes sequence".format( 

244 "crypto_core_ed25519_SCALARBYTES" 

245 ), 

246 raising=exc.TypeError, 

247 ) 

248 

249 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

250 

251 lib.crypto_core_ed25519_scalar_complement(r, s) 

252 

253 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:] 

254 

255 

256def crypto_core_ed25519_scalar_add(p: bytes, q: bytes) -> bytes: 

257 """ 

258 Add integers ``p`` and ``q`` modulo ``L``, where ``L`` is the order of 

259 the main subgroup. 

260 

261 :param p: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

262 long bytes sequence representing an integer 

263 :type p: bytes 

264 :param q: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

265 long bytes sequence representing an integer 

266 :type q: bytes 

267 :return: an integer represented as a 

268 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

269 :rtype: bytes 

270 :raises nacl.exceptions.UnavailableError: If called when using a 

271 minimal build of libsodium. 

272 """ 

273 ensure( 

274 has_crypto_core_ed25519, 

275 "Not available in minimal build", 

276 raising=exc.UnavailableError, 

277 ) 

278 

279 ensure( 

280 isinstance(p, bytes) 

281 and isinstance(q, bytes) 

282 and len(p) == crypto_core_ed25519_SCALARBYTES 

283 and len(q) == crypto_core_ed25519_SCALARBYTES, 

284 "Each integer must be a {} long bytes sequence".format( 

285 "crypto_core_ed25519_SCALARBYTES" 

286 ), 

287 raising=exc.TypeError, 

288 ) 

289 

290 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

291 

292 lib.crypto_core_ed25519_scalar_add(r, p, q) 

293 

294 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:] 

295 

296 

297def crypto_core_ed25519_scalar_sub(p: bytes, q: bytes) -> bytes: 

298 """ 

299 Subtract integers ``p`` and ``q`` modulo ``L``, where ``L`` is the 

300 order of the main subgroup. 

301 

302 :param p: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

303 long bytes sequence representing an integer 

304 :type p: bytes 

305 :param q: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

306 long bytes sequence representing an integer 

307 :type q: bytes 

308 :return: an integer represented as a 

309 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

310 :rtype: bytes 

311 :raises nacl.exceptions.UnavailableError: If called when using a 

312 minimal build of libsodium. 

313 """ 

314 ensure( 

315 has_crypto_core_ed25519, 

316 "Not available in minimal build", 

317 raising=exc.UnavailableError, 

318 ) 

319 

320 ensure( 

321 isinstance(p, bytes) 

322 and isinstance(q, bytes) 

323 and len(p) == crypto_core_ed25519_SCALARBYTES 

324 and len(q) == crypto_core_ed25519_SCALARBYTES, 

325 "Each integer must be a {} long bytes sequence".format( 

326 "crypto_core_ed25519_SCALARBYTES" 

327 ), 

328 raising=exc.TypeError, 

329 ) 

330 

331 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

332 

333 lib.crypto_core_ed25519_scalar_sub(r, p, q) 

334 

335 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:] 

336 

337 

338def crypto_core_ed25519_scalar_mul(p: bytes, q: bytes) -> bytes: 

339 """ 

340 Multiply integers ``p`` and ``q`` modulo ``L``, where ``L`` is the 

341 order of the main subgroup. 

342 

343 :param p: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

344 long bytes sequence representing an integer 

345 :type p: bytes 

346 :param q: a :py:data:`.crypto_core_ed25519_SCALARBYTES` 

347 long bytes sequence representing an integer 

348 :type q: bytes 

349 :return: an integer represented as a 

350 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

351 :rtype: bytes 

352 :raises nacl.exceptions.UnavailableError: If called when using a 

353 minimal build of libsodium. 

354 """ 

355 ensure( 

356 has_crypto_core_ed25519, 

357 "Not available in minimal build", 

358 raising=exc.UnavailableError, 

359 ) 

360 

361 ensure( 

362 isinstance(p, bytes) 

363 and isinstance(q, bytes) 

364 and len(p) == crypto_core_ed25519_SCALARBYTES 

365 and len(q) == crypto_core_ed25519_SCALARBYTES, 

366 "Each integer must be a {} long bytes sequence".format( 

367 "crypto_core_ed25519_SCALARBYTES" 

368 ), 

369 raising=exc.TypeError, 

370 ) 

371 

372 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

373 

374 lib.crypto_core_ed25519_scalar_mul(r, p, q) 

375 

376 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:] 

377 

378 

379def crypto_core_ed25519_scalar_reduce(s: bytes) -> bytes: 

380 """ 

381 Reduce integer ``s`` to ``s`` modulo ``L``, where ``L`` is the order 

382 of the main subgroup. 

383 

384 :param s: a :py:data:`.crypto_core_ed25519_NONREDUCEDSCALARBYTES` 

385 long bytes sequence representing an integer 

386 :type s: bytes 

387 :return: an integer represented as a 

388 :py:data:`.crypto_core_ed25519_SCALARBYTES` long bytes sequence 

389 :rtype: bytes 

390 :raises nacl.exceptions.UnavailableError: If called when using a 

391 minimal build of libsodium. 

392 """ 

393 ensure( 

394 has_crypto_core_ed25519, 

395 "Not available in minimal build", 

396 raising=exc.UnavailableError, 

397 ) 

398 

399 ensure( 

400 isinstance(s, bytes) 

401 and len(s) == crypto_core_ed25519_NONREDUCEDSCALARBYTES, 

402 "Integer s must be a {} long bytes sequence".format( 

403 "crypto_core_ed25519_NONREDUCEDSCALARBYTES" 

404 ), 

405 raising=exc.TypeError, 

406 ) 

407 

408 r = ffi.new("unsigned char[]", crypto_core_ed25519_SCALARBYTES) 

409 

410 lib.crypto_core_ed25519_scalar_reduce(r, s) 

411 

412 return ffi.buffer(r, crypto_core_ed25519_SCALARBYTES)[:]