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?

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/
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];
    // ...

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


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>
		//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
            			|| "mult",
            			|lc| lc + document,
            			|lc| lc + redactor,
            			|lc| lc + redacted


But this gives me error,

error[E0599]: no method named `ok_or` found for type parameter `S` in the current scope
   --> src/
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/
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/
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.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.