Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,8 @@ jobs:
- name: Run cargo clippy (tests)
run: cargo clippy --tests -- -D warnings

- name: Run cargo clippy (bench)
run: cargo clippy --bench -- -D warnings
- name: Run cargo clippy (bench bls381_benches)
run: cargo clippy --bench bls381_benches -- -D warnings

- name: Run cargo clippy (bench multi_verify_benches)
run: cargo clippy --bench multi_verify_benches -- -D warnings
188 changes: 188 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# multiversx-bls for Rust

This is a wrapper library of [bls](https://github.com/herumi/bls/), that bridges the functionality with MultiversX [crypto packages](https://github.com/multiversx/mx-chain-crypto-go).

## Spec Name

multiversx-bls | Spec Name|
------|-----------------|
G1|Signature|
G2|Public Key|

## G1 - Signature

`verify(&self, public_key: G2, msg: &[u8]) -> bool`

- Checks if self is a valid signature of message for the given public key.

`fast_aggregate_verify(&self, public_keys: &[G2], msg: &[u8]) -> bool`

- Checks if self is a valid aggregated signature of message for multiple public keys.

`add_assign(&mut self, signature: G1)`

- Adds another signature to self (signature aggregation).

`is_valid_order(&self) -> bool`

- Checks if self is a valid signature of the correct group order.

`aggregate(&mut self, sigs: &[G1])`

- Sets self as the aggregated signature of signatures.

`is_zero(&self) -> bool`

- Checks if self is the point at infinity (zero element).

`is_valid(&self) -> boo`l

- Checks if self is a valid G1 element.

`verify_signature_order(verify: bool)`

- Enables or disables signature order verification:
- `true`: verification enabled;
- `false`: verification disabled (default).

`deserialize(&mut self, buf: &[u8]) -> bool`

- Deserialize a signature from an array of bytes.

`from_serialized(buf: &[u8]) -> Result<Self, BlsError>`

- Creates a new G1 element from a serialized buffer:
- G1 if successful;
- Return `BlsError::InvalidData` on failure.

`serialize(&self) -> Result<Vec<u8>, BlsError>`

- Serializes the signature into a vector of bytes:
- A vector of bytes if successful;
- Return `BlsError::SerializeError` on failure.

## G2 - Public Key

`add_assign(&mut self, public_key: G2)`

- Adds another public key to self.

`is_valid_order(&self) -> bool`

- Checks if self is a valid public key of the correct group order.

`set_str(&mut self, s: &str)`

- Sets the G2 element from a **base-10** string.

`deserialize_g2(&mut self, buf: &[u8]) -> bool`

- Deserializes a G2 element from a byte buffer.

`is_zero(&self) -> bool`

- Checks if self is the point at infinity (zero element).

`is_valid(&self) -> bool`

- Checks if self is a valid G2 element.

`verify_public_key_order(verify: bool)`

- Enables/disables verification of public key order when setting keys:
- true: verification enabled;
- false: verification disabled (default).

`serialize(&self) -> Result<Vec<u8>, BlsError>`

- Serializes the public key into a byte array.
- A vector of bytes if successful;
- Return `BlsError::SerializeError` on failure.

`deserialize(&mut self, buf: &[u8]) -> bool`

- Deserializes a public key from a byte array.

`from_serialized(buf: &[u8]) -> Result<Self, BlsError>`

- Creates a new G2 element from a serialized buffer:
- Returns G2 if successful;
- Returns `BlsError::InvalidData` otherwise.

## Secret Key

`set_by_csprng(&mut self)`

- Initializes the secret key using a cryptographically secure random number generator (CSPRNG). Panics if the generated key is zero.

`set_hex_str(&mut self, s: &str) -> bool`

- Sets the secret key from a hexadecimal string.

`from_hex_str(s: &str) -> Result<SecretKey, BlsError>`

- Creates a new secret key from a hexadecimal string:
- Returns SecretKey if valid;
- Returns `BlsError::InvalidData` if invalid.

`get_public_key(&self) -> G2`

- Derives the public key (G2) corresponding to this secret key.

`sign(&self, msg: &[u8]) -> G1`

- Generates a signature (G1) of the given message.

`deserialize(&mut self, buf: &[u8]) -> bool`

- Deserializes a secret key from a byte array. Returns true if successful and length matches.

`from_serialized(buf: &[u8]) -> Result<Self, BlsError>`

- Creates a new secret key from serialized data:
- Returns SecretKey if valid;
- Returns `BlsError::InvalidData` if invalid.

`serialize(&self) -> Result<Vec<u8>, BlsError>`

- Serializes the secret key into a byte array:
- A vector of bytes if successful;
- Return `BlsError::SerializeError` on failure.

## Executors

- Executors are extracted from [bls-go-binary](https://github.com/herumi/bls-go-binary), version `v1.28.2`.

## Usage

Example: creating a public key from a vector of bytes.

```rust
let buffer = [0; 96];

let mut public_key = G2::default();

if !public_key.deserialize_g2(buffer) {
return Err(BlsError::InvalidData);
}
```

Example: creating a signature from a vector of bytes.

```rust
let buffer = [0; 48];

let mut sign = G1::default();

if !sign.deserialize(buffer) {
return Err(BlsError::InvalidData);
}
```

Example: verifying a BLS signature with a single public key and message.

```rust
fn verify_signature(signature: G1, public_key: G2, message: &[u8]) {
signature.verify(public_key, message)
}
```
83 changes: 0 additions & 83 deletions readme.md

This file was deleted.

92 changes: 55 additions & 37 deletions src/bls_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,75 @@ use crate::gt::GT;
use crate::secret_key::SecretKey;

unsafe extern "C" {
pub fn blsInit(curve: usize, compiledTimeVar: usize) -> i32;

pub fn mclBnFr_isZero(secret_key: *const SecretKey) -> i32;
pub fn mclBn_getFrByteSize() -> usize;
pub fn mclBn_getFpByteSize() -> usize;
pub fn mclBnG2_setStr(x: *mut G2, buf: *const u8, buf_size: usize, io_mode: i32) -> i32;
pub fn mclBnG2_deserialize(x: *mut G2, buf: *const u8, buf_size: usize) -> usize;
pub fn mclBnG2_isZero(x: *const G2) -> u8;
pub fn mclBnG2_isValid(x: *const G2) -> u8;

pub fn mclBnG1_isZero(x: *const G1) -> u8;
pub fn mclBnG1_isValid(x: *const G1) -> u8;

pub fn blsSecretKeySetByCSPRNG(x: *mut SecretKey);
pub fn blsSecretKeySetHexStr(x: *mut SecretKey, buf: *const u8, buf_size: usize) -> i32;
pub fn blsGetPublicKey(y: *mut G2, x: *const SecretKey);
pub fn blsSignatureVerifyOrder(do_verify: i32);
pub fn blsSignatureIsValidOrder(sig: *const G1) -> i32;
pub fn blsPublicKeyVerifyOrder(do_verify: i32);
pub fn blsPublicKeyIsValidOrder(public_key: *const G2) -> i32;

pub fn blsSign(sig: *mut G1, secret_key: *const SecretKey, msg: *const u8, msg_len: usize);
pub fn blsVerify(sig: *const G1, public_key: *const G2, msg: *const u8, msg_len: usize) -> i32;
pub fn blsFastAggregateVerify(
pub unsafe fn blsInit(curve: usize, compiledTimeVar: usize) -> i32;

pub unsafe fn mclBnFr_isZero(secret_key: *const SecretKey) -> i32;
pub unsafe fn mclBn_getFrByteSize() -> usize;
pub unsafe fn mclBn_getFpByteSize() -> usize;
pub unsafe fn mclBnG2_setStr(x: *mut G2, buf: *const u8, buf_size: usize, io_mode: i32) -> i32;
pub unsafe fn mclBnG2_deserialize(x: *mut G2, buf: *const u8, buf_size: usize) -> usize;
pub unsafe fn mclBnG2_isZero(x: *const G2) -> u8;
pub unsafe fn mclBnG2_isValid(x: *const G2) -> u8;

pub unsafe fn mclBnG1_isZero(x: *const G1) -> u8;
pub unsafe fn mclBnG1_isValid(x: *const G1) -> u8;

pub unsafe fn blsSecretKeySetByCSPRNG(x: *mut SecretKey);
pub unsafe fn blsSecretKeySetHexStr(x: *mut SecretKey, buf: *const u8, buf_size: usize) -> i32;
pub unsafe fn blsGetPublicKey(y: *mut G2, x: *const SecretKey);
pub unsafe fn blsSignatureVerifyOrder(do_verify: i32);
pub unsafe fn blsSignatureIsValidOrder(sig: *const G1) -> i32;
pub unsafe fn blsPublicKeyVerifyOrder(do_verify: i32);
pub unsafe fn blsPublicKeyIsValidOrder(public_key: *const G2) -> i32;

pub unsafe fn blsSign(
sig: *mut G1,
secret_key: *const SecretKey,
msg: *const u8,
msg_len: usize,
);
pub unsafe fn blsVerify(
sig: *const G1,
public_key: *const G2,
msg: *const u8,
msg_len: usize,
) -> i32;
pub unsafe fn blsFastAggregateVerify(
sig: *const G1,
public_key: *const G2,
public_keys_len: usize,
msg: *const u8,
msg_len: usize,
) -> i32;

pub fn blsAggregateSignature(
pub unsafe fn blsAggregateSignature(
aggregate_sig: *mut G1,
signature: *const G1,
signatures_len: usize,
);

pub fn blsSecretKeyIsEqual(lhs: *const SecretKey, rhs: *const SecretKey) -> i32;
pub fn blsPublicKeyIsEqual(lhs: *const G2, rhs: *const G2) -> i32;
pub fn blsSignatureIsEqual(lhs: *const G1, rhs: *const G1) -> i32;
pub unsafe fn blsSecretKeyIsEqual(lhs: *const SecretKey, rhs: *const SecretKey) -> i32;
pub unsafe fn blsPublicKeyIsEqual(lhs: *const G2, rhs: *const G2) -> i32;
pub unsafe fn blsSignatureIsEqual(lhs: *const G1, rhs: *const G1) -> i32;

pub fn blsSecretKeySerialize(buf: *mut u8, max_buf_len: usize, x: *const SecretKey) -> usize;
pub fn blsPublicKeySerialize(buf: *mut u8, max_buf_len: usize, x: *const G2) -> usize;
pub fn blsSignatureSerialize(buf: *mut u8, max_buf_len: usize, x: *const G1) -> usize;
pub unsafe fn blsSecretKeySerialize(
buf: *mut u8,
max_buf_len: usize,
x: *const SecretKey,
) -> usize;
pub unsafe fn blsPublicKeySerialize(buf: *mut u8, max_buf_len: usize, x: *const G2) -> usize;
pub unsafe fn blsSignatureSerialize(buf: *mut u8, max_buf_len: usize, x: *const G1) -> usize;

pub fn blsSecretKeyDeserialize(x: *mut SecretKey, buf: *const u8, buf_len: usize) -> usize;
pub fn blsPublicKeyDeserialize(x: *mut G2, buf: *const u8, buf_len: usize) -> usize;
pub fn blsSignatureDeserialize(x: *mut G1, buf: *const u8, buf_len: usize) -> usize;
pub unsafe fn blsSecretKeyDeserialize(
x: *mut SecretKey,
buf: *const u8,
buf_len: usize,
) -> usize;
pub unsafe fn blsPublicKeyDeserialize(x: *mut G2, buf: *const u8, buf_len: usize) -> usize;
pub unsafe fn blsSignatureDeserialize(x: *mut G1, buf: *const u8, buf_len: usize) -> usize;

pub fn blsPublicKeyAdd(public_key_1: *mut G2, public_key_2: *const G2);
pub fn blsSignatureAdd(signature_1: *mut G1, signature_2: *const G1);
pub unsafe fn blsPublicKeyAdd(public_key_1: *mut G2, public_key_2: *const G2);
pub unsafe fn blsSignatureAdd(signature_1: *mut G1, signature_2: *const G1);

pub fn mclBnGT_isEqual(lhs: *const GT, rhs: *const GT) -> i32;
pub unsafe fn mclBnGT_isEqual(lhs: *const GT, rhs: *const GT) -> i32;
}
Loading