Array of field elements

I was wondering if we can actually make an array of field elements from array of u8 integers.
For instance,
We have,

struct RedactDemo<S: PrimeField> {
	document: Option<S>,
}

But if I try,

struct RedactDemo<S: PrimeField> {
	a: Option<[S;10]>,
}

This does not work. Is there any way I can sort this out? Like how does one instantiate an array of field elements. Also if we assume that

let mut a: [S;10] = [0;10];

By 0 I mean 0 in the field, it does not work. Can someone please tell me a way about it?
Thanks!

Where exactly does it fail in what way? I mean, one problem is that you need a conversion to get an S from the constant 0.

I have a function which converts u8 to PrimeField element. I name it as u8_to_prime
The error I get is

error[E0038]: the trait `PrimeField` cannot be made into an object
   --> src/main.rs:49:17
    |
49  |     let mut test: [ff::PrimeField;LEN] = [u8_to_prime(null);LEN];
    |                    ^^^^^^^^^^^^^^ `PrimeField` cannot be made into an object
    |

My code is

let null: u8 = 0;
let mut test: [ff::PrimeField;LEN] = [u8_to_prime(null);LEN];

This is just for test, I want to have something like

struct Demo<S: PrimeField>{
            a: Option<[S;10]>
}

My question is what is the way to write this?

ff::PrimeField is not a type. It's a trait, which may be implemented by any number of types.

If you know which prime field you want to use, you can specify a particular type that implements the PrimeField trait:

let mut test: [bls12_381::Scalar; LEN] = [u8_to_prime(null); LEN];

Or if you want this code to be generic over any prime field, you can use a type parameter and let the caller choose the concrete type:

fn do_stuff<S: PrimeField>() {
    let null: u8 = 0;
    let mut test: [S; LEN] = [u8_to_prime(null); LEN];
    // ...
}
2 Likes

Ah I see, I understand it now. I was using scalar but was not sure if I was doing right.

Thanks!

Actually on similar lines, I want to make a circuit where A[i]*B[i] = C[i]
That is checking point wise.
I am writing circuit as follows

//implementation of the demo circuit 
impl <S: PrimeField> Circuit<S>  for RedactDemo<S>{
  fn synthesize<CS: ConstraintSystem<S>>(self, cs: &mut CS) -> Result<(), SynthesisError>
	{
		//assert_eq!(LEN);		
		//private input	
		for i in 1..LEN{
		let document_value = self.document.unwrap();	
		let document = cs.alloc(|| "document",|| document_value[i].ok_or(SynthesisError::AssignmentMissing))?;
		//public input
		let redactor_value = self.redactor.unwrap();	
		let redactor = cs.alloc(|| "redactor",|| redactor_value[i].ok_or(SynthesisError::AssignmentMissing))?;
		let redacted = cs.alloc_input(|| "redacted", || self.redacted.unwrap()[i].ok_or(SynthesisError::AssignmentMissing))?;

		//enforcing the fact that indeed a*b = w, using multiplication gate
		cs.enforce(
            			|| "mult",
            			|lc| lc + document,
            			|lc| lc + redactor,
            			|lc| lc + redacted
        		  );
		}
		Ok(())
	}

}

But this gives me error,

error[E0599]: no method named `ok_or` found for type parameter `S` in the current scope
   --> src/main.rs:149:62
    |
149 |         let document = cs.alloc(|| "document",|| document_value[i].ok_or(SynthesisError::AssignmentMissing))?;
    |                                                                    ^^^^^ method not found in `S`

error[E0599]: no method named `ok_or` found for type parameter `S` in the current scope
   --> src/main.rs:152:62
    |
152 |         let redactor = cs.alloc(|| "redactor",|| redactor_value[i].ok_or(SynthesisError::AssignmentMissing))?;
    |                                                                    ^^^^^ method not found in `S`

error[E0599]: no method named `ok_or` found for type parameter `S` in the current scope
   --> src/main.rs:153:77
    |
153 |         let redacted = cs.alloc_input(|| "redacted", || self.redacted.unwrap()[i].ok_or(SynthesisError::AssignmentMissing))?;
    |                                                                                   ^^^^^ method not found in `S`

The problem is I do understand the error. But, I want to give entire array in and check at each point if document*redactor == redacted
Any suggestions as to what should be done? Also, I am working in library bellman

The ok_or is necessary only if you have an Option<S> and want to make sure it is set to Some(S).

If document_value has elements of type S then you should be able to write something like:

let document = cs.alloc(|| "document", || Ok(document_value[i]))?;

Yes indeed I have option and am giving some values, I also printed out the values just to verify.

struct RedactDemo<S: PrimeField> {
	document: Option<[S;LEN]>,
	redactor: Option<[S;LEN]> ,
	redacted: Option<[S;LEN]>, 

}

and then we have

let c = RedactDemo{
		document: Some(document),
		redactor: Some(redactor),
		redacted: Some(redacted),		
	};

That's the reason I know the option will have an array of elements in the field. But translating the verification to a circuit is getting complicated.

RedactDemo::document is an Option<[S; LEN]>, but you have already unwrapped it, so document_value is not an Option, it is just an array [S; LEN]. And an individual element like document_value[i] has type S.

So instead of calling Option::ok_or (which is used to convert from Option to Result), you can simply use Ok(...) to construct a Result.

You should read the book chapters on enums and error handling if you haven't made it there yet.