midnight_circuits/instructions/base64.rs
1// This file is part of MIDNIGHT-ZK.
2// Copyright (C) Midnight Foundation
3// SPDX-License-Identifier: Apache-2.0
4// Licensed under the Apache License, Version 2.0 (the "License");
5// You may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7// http://www.apache.org/licenses/LICENSE-2.0
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14//! Set of Base64 instructions.
15use midnight_proofs::{
16 circuit::{Layouter, Value},
17 plonk::Error,
18};
19
20use crate::{
21 types::{AssignedByte, AssignedVector},
22 CircuitField,
23};
24
25/// This trait defines methods for converting data encoded in standard Base64 or
26/// Base64URL (URL-safe) format into its raw byte representation.
27pub trait Base64Instructions<F: CircuitField> {
28 /// Receives a base64 url-safe encoded string as [AssignedByte]s and returns
29 /// the decoded ASCII string as a vector of [AssignedByte].
30 /// If `padded` is selected, the input length must be a multiple of 4.
31 ///
32 /// The length of the output is always 3/4 of the padded input's length.
33 /// In order to reach this length, the output will be completed with one or
34 /// two ASCII_ZERO chars if necessary.
35 ///
36 /// # Panics
37 ///
38 /// If `padded` = true and the input length is not a multiple of 4.
39 fn decode_base64url(
40 &self,
41 layouter: &mut impl Layouter<F>,
42 b64url_input: &[AssignedByte<F>],
43 padded: bool,
44 ) -> Result<Vec<AssignedByte<F>>, Error>;
45
46 /// Receives a base64 encoded string as [AssignedByte]s and returns
47 /// the decoded ASCII string as a vector of [AssignedByte].
48 /// If `padded` is selected, the input length must be a multiple of 4.
49 ///
50 /// The length of the output is always 3/4 of the padded input's length.
51 /// In order to reach this length, the output will be completed with one or
52 /// two ASCII_ZERO chars if necessary.
53 ///
54 /// # Panics
55 ///
56 /// If `padded` = true and the input length is not a multiple of 4.
57 fn decode_base64(
58 &self,
59 layouter: &mut impl Layouter<F>,
60 b64_input: &[AssignedByte<F>],
61 padded: bool,
62 ) -> Result<Vec<AssignedByte<F>>, Error>;
63}
64
65/// An AssignedVector with additional assumptions:
66/// 1. The filler elements in the vector are present in the Base64 table, and
67/// therefore, we can decode the whole buffer.
68/// 2. The length of the vector is a multiple of 4. This is guaranteed for
69/// every padded base64 string.
70///
71/// Note:
72/// These extra assumptions guarantee completeness.
73/// Soundness is always guaranteed.
74#[derive(Debug, Clone)]
75pub struct Base64Vec<F: CircuitField, const M: usize, const A: usize>(
76 pub(crate) AssignedVector<F, AssignedByte<F>, M, A>,
77);
78
79impl<F: CircuitField, const M: usize, const A: usize> From<Base64Vec<F, M, A>>
80 for AssignedVector<F, AssignedByte<F>, M, A>
81{
82 fn from(value: Base64Vec<F, M, A>) -> Self {
83 value.0
84 }
85}
86
87/// Equivalent to Base64Instructions for variable-length inputs.
88pub trait Base64VarInstructions<F: CircuitField, const M: usize, const A: usize>:
89 Base64Instructions<F>
90{
91 /// Assigns a vector of bytes into Base64Vec.
92 ///
93 /// # Panics
94 ///
95 /// If |value| > M or 4 does not divide |value|.
96 fn assign_var_base64(
97 &self,
98 layouter: &mut impl Layouter<F>,
99 value: Value<Vec<u8>>,
100 ) -> Result<Base64Vec<F, M, A>, Error>;
101
102 /// Returns a Base64Vec from an AssignedVector.
103 fn base64_from_vec(
104 &self,
105 layouter: &mut impl Layouter<F>,
106 vec: &AssignedVector<F, AssignedByte<F>, M, A>,
107 ) -> Result<Base64Vec<F, M, A>, Error>;
108
109 /// Variable length equivalent of `decode_base64_url` in
110 /// `Base64Instructions`. Inputs must always be padded apropriately
111 /// according to the base64 format.
112 fn var_decode_base64url<const M_OUT: usize, const A_OUT: usize>(
113 &self,
114 layouter: &mut impl Layouter<F>,
115 b64url_input: &Base64Vec<F, M, A>,
116 ) -> Result<AssignedVector<F, AssignedByte<F>, M_OUT, A_OUT>, Error>;
117
118 /// Equivalent of `decode_base64` in `Base64Instructions`.
119 /// Inputs must always be padded apropriately according to the base64
120 /// format.
121 fn var_decode_base64<const M_OUT: usize, const A_OUT: usize>(
122 &self,
123 layouter: &mut impl Layouter<F>,
124 b64_input: &Base64Vec<F, M, A>,
125 ) -> Result<AssignedVector<F, AssignedByte<F>, M_OUT, A_OUT>, Error>;
126}