arnaucube
arnaucube/grapevine-sonobePublic Self-hosted repository
grapevine-sonobe/src/utils/inputs.rs
src/utils/inputs.rsRaw
 1use ark_ff::{PrimeField, BigInteger};
 2use ark_pallas::Fr;
 3use ark_std::rand::rngs::OsRng;
 4use std::error::Error;
 5use num_bigint::{BigInt, Sign::Plus, RandBigInt};
 6
 7use super::{MAX_SECRET_LENGTH, MAX_USERNAME_LENGTH, SECRET_FIELD_LENGTH};
 8
 9/** Get the starting ivc inputs (z0) for the grapevine circuit */
10pub fn get_z0<F: PrimeField>() -> [F; 4] {
11    (0..4).map(|_| F::zero()).collect::<Vec<F>>().try_into().unwrap()
12}
13
14/** Generates a random field element for given field as bigint */
15pub fn random_f_bigint<F: PrimeField>() -> BigInt {
16    let lower_bound = BigInt::from(0);
17    let upper_bound = BigInt::from_bytes_be(Plus, &F::MODULUS.to_bytes_be());
18    OsRng.gen_bigint_range(&lower_bound, &upper_bound)
19}
20
21/**
22 * Converts a given word to array of 6 field elements
23 * @dev split into 31-byte strings to fit in finite field and pad with 0's where necessary
24 *
25 * @param phrase - the string entered by user to compute hash for (will be length checked)
26 * @return - array of 6 Fr elements
27 */
28pub fn serialize_phrase(
29    phrase: &String,
30) -> Result<[BigInt; SECRET_FIELD_LENGTH], Box<dyn Error>> {
31    // check length
32    if phrase.len() > MAX_SECRET_LENGTH {
33        return Err("Phrase must be <= 180 characters".into());
34    }
35    // convert each 31-byte chunk to field element
36    let mut chunks: [BigInt; SECRET_FIELD_LENGTH] = Default::default();
37    for i in 0..SECRET_FIELD_LENGTH {
38        // get the range
39        let start = i * 31;
40        let end = (i + 1) * 31;
41        let mut chunk: [u8; 32] = [0; 32];
42        // select slice from range and pad if needed
43        if start >= phrase.len() {
44        } else if end > phrase.len() {
45            chunk[1..(phrase.len() - start + 1)].copy_from_slice(&phrase.as_bytes()[start..]);
46        } else {
47            chunk[1..32].copy_from_slice(&phrase.as_bytes()[start..end]);
48        }
49        // wrap in field element
50        chunks[i] = BigInt::from_bytes_be(Plus, &chunk);
51    }
52    Ok(chunks)
53}
54
55/**
56* Converts a given username to a field element
57*
58* @param username - the username to convert to utf8 and into field element
59* @return - the username serialied into the field element
60*/
61pub fn serialize_username(username: &String) -> Result<BigInt, Box<dyn Error>> {
62    // check length
63    if username.len() > MAX_USERNAME_LENGTH {
64        return Err("Username must be <= 30 characters".into());
65    }
66    // convert to big endian bytes
67    let mut bytes: [u8; 32] = [0; 32];
68    bytes[1..(username.len() + 1)].copy_from_slice(&username.as_bytes()[..]);
69    // convert to bigint
70    Ok(BigInt::from_bytes_be(Plus, &bytes))
71}