1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! BLS12-381 pairing-friendly elliptic curve implementation.
//!
//! This module exposes low-level group, scalar, RFC 9380 hash-to-curve, and
//! pairing primitives. It does not implement a complete BLS signature
//! ciphersuite (including key generation, proof of possession, aggregation,
//! or protocol-specific input validation).
//!
//! The following demonstrates the core equation used by an Eth2-style
//! minimum-public-key-size construction. Production code must derive a
//! nonzero secret scalar with the selected ciphersuite's key-generation
//! procedure, keep its encoded form in zeroizing storage, and enforce that
//! ciphersuite's validation rules. `Bls12_381Scalar` is a generic `Copy` field
//! element for public arithmetic, not a protected secret-key container. The
//! low-level `msm_vartime` helpers likewise accept public scalars only. Secret
//! scalar multiplication must use `multiply_secret_be_bytes`, or callers should
//! use the high-level BLS types in `dcrypt-sign`.
//! External public keys should be decoded with
//! `G1Projective::from_bytes_validated`, which rejects the identity. Complete
//! BLS ciphersuites have more nuanced signature identity rules, so callers
//! should use the high-level types in `dcrypt-sign` rather than assembling a
//! signature protocol from these primitives.
//!
//! ```
//! use dcrypt_algorithms::ec::bls12_381::{
//! pairing, G1Affine, G1Projective, G2Affine, G2Projective,
//! };
//! use dcrypt_api::types::SecretBytes;
//!
//! // Demonstration only: KeyGen normally derives 48 pseudorandom OKM bytes
//! // using HKDF and reduces it modulo r. SecretBytes owns and clears the
//! // resulting canonical big-endian scalar.
//! let mut encoded_secret = [0u8; 32];
//! encoded_secret[31] = 42;
//! let secret_bytes = SecretBytes::new(encoded_secret);
//!
//! let public_key = G1Affine::from(
//! G1Projective::generator().multiply_secret_be_bytes(&secret_bytes)?,
//! );
//! let message_point = G2Projective::hash_to_curve(
//! b"message",
//! b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_",
//! )?;
//! let signature = G2Affine::from(message_point.multiply_secret_be_bytes(&secret_bytes)?);
//! let message_point = G2Affine::from(message_point);
//!
//! assert_eq!(
//! pairing(&public_key, &message_point),
//! pairing(&G1Affine::generator(), &signature),
//! );
//! drop(secret_bytes);
//! # Ok::<(), dcrypt_algorithms::Error>(())
//! ```
// External crates
extern crate alloc;
// Module declarations
// Internal use for submodules
use crateResult;
use Scalar;
// Public API exports (following dcrypt conventions)
pub use Scalar as Bls12_381Scalar;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
// BLS curve parameters
/// BLS parameter x = -0xd201000000010000
const BLS_X: u64 = 0xd201_0000_0001_0000;
/// Sign of BLS parameter x
const BLS_X_IS_NEGATIVE: bool = true;