LLZK 2.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
Field.h
Go to the documentation of this file.
1//===-- Field.h -------------------------------------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
10#pragma once
11
14
15#include <mlir/IR/BuiltinOps.h>
16#include <mlir/Support/LLVM.h>
17
18#include <llvm/ADT/DenseMap.h>
19#include <llvm/ADT/DynamicAPInt.h>
20#include <llvm/ADT/SmallSet.h>
21#include <llvm/Support/LogicalResult.h>
22#include <llvm/Support/SMTAPI.h>
23
24#include <functional>
25#include <optional>
26#include <string_view>
27
28namespace llzk {
29
35class Field {
36public:
39 inline static void
40 addField(llvm::StringRef fieldName, const llvm::APInt &prime, EmitErrorFn errFn) {
41 return addField(Field(prime, fieldName), errFn);
42 }
43 inline static void
44 addField(llvm::StringRef fieldName, llvm::StringRef primeStr, EmitErrorFn errFn) {
45 return addField(Field(primeStr, fieldName), errFn);
46 }
47
51 static llvm::FailureOr<std::reference_wrapper<const Field>>
52 tryGetField(llvm::StringRef fieldName);
53
55 static llvm::LogicalResult verifyFieldDefined(llvm::StringRef fieldName, EmitErrorFn errFn);
56
60 static const Field &getField(llvm::StringRef fieldName, EmitErrorFn errFn);
61 inline static const Field &getField(llvm::StringRef fieldName) {
62 return getField(fieldName, nullptr);
63 }
64
65 Field() = delete;
66 Field(const Field &) = default;
67 Field(Field &&) noexcept = default;
68 Field &operator=(const Field &) = default;
69
71 llvm::DynamicAPInt prime() const { return primeMod; }
72
74 llvm::DynamicAPInt half() const { return halfPrime; }
75
77 inline llvm::DynamicAPInt felt(int i) const { return reduce(i); }
78
80 inline llvm::DynamicAPInt zero() const { return felt(0); }
81
83 inline llvm::DynamicAPInt one() const { return felt(1); }
84
86 inline llvm::DynamicAPInt maxVal() const { return prime() - one(); }
87
89 llvm::DynamicAPInt inv(const llvm::DynamicAPInt &i) const;
90
91 llvm::DynamicAPInt inv(const llvm::APInt &i) const;
92
96 llvm::DynamicAPInt reduce(const llvm::DynamicAPInt &i) const;
97 inline llvm::DynamicAPInt reduce(int i) const { return reduce(llvm::DynamicAPInt(i)); }
98 llvm::DynamicAPInt reduce(const llvm::APInt &i) const;
99
104 llvm::DynamicAPInt toSigned(const llvm::DynamicAPInt &i) const;
105
106 inline unsigned bitWidth() const { return bitwidth; }
107
108 inline llvm::StringRef name() const { return primeName; }
109
111 llvm::SMTExprRef createSymbol(const llvm::SMTSolverRef &solver, const char *name) const {
112 return solver->mkSymbol(name, solver->getBitvectorSort(bitWidth()));
113 }
114
115 friend bool operator==(const Field &lhs, const Field &rhs) {
116 return lhs.primeMod == rhs.primeMod;
117 }
118
119 friend bool operator<(const Field &lhs, const Field &rhs) {
120 return std::tie(lhs.primeMod, lhs.primeName, lhs.bitwidth, lhs.halfPrime) <
121 std::tie(rhs.primeMod, rhs.primeName, rhs.bitwidth, rhs.halfPrime);
122 }
123
124private:
125 Field(std::string_view primeStr, llvm::StringRef name);
126 Field(const llvm::APInt &primeInt, llvm::StringRef name);
127
129 llvm::StringRef primeName;
130 llvm::DynamicAPInt primeMod, halfPrime;
131 unsigned bitwidth;
132
134 static void initKnownFields();
135
138 static void addField(Field &&f, EmitErrorFn errFn);
139 inline static void addField(Field &&f) { addField(std::move(f), nullptr); }
140};
141
149llvm::LogicalResult addSpecifiedFields(mlir::ModuleOp modOp);
150
152using FieldRef = std::reference_wrapper<const Field>;
153
155using FieldSet = llvm::SmallSet<FieldRef, 2>;
156
162mlir::LogicalResult collectFields(mlir::Operation *root, FieldSet &fields, bool silent = true);
163
168std::optional<std::reference_wrapper<const Field>> tryDetectSpecifiedField(mlir::Operation *root);
169
170} // namespace llzk
This file implements helper methods for constructing DynamicAPInts.
Information about the prime finite field used for the interval analysis.
Definition Field.h:35
static void addField(llvm::StringRef fieldName, llvm::StringRef primeStr, EmitErrorFn errFn)
Definition Field.h:44
llvm::DynamicAPInt half() const
Returns p / 2.
Definition Field.h:74
static llvm::FailureOr< std::reference_wrapper< const Field > > tryGetField(llvm::StringRef fieldName)
Get a Field from a given field name string, or failure if the field is not defined.
Definition Field.cpp:50
friend bool operator==(const Field &lhs, const Field &rhs)
Definition Field.h:115
Field()=delete
Field(const Field &)=default
llvm::DynamicAPInt zero() const
Returns 0 at the bitwidth of the field.
Definition Field.h:80
llvm::DynamicAPInt toSigned(const llvm::DynamicAPInt &i) const
Converts a canonical field element to its signed integer representation: toSigned(f) = f if f < field...
Definition Field.cpp:131
llvm::DynamicAPInt prime() const
For the prime field p, returns p.
Definition Field.h:71
llvm::DynamicAPInt reduce(const llvm::DynamicAPInt &i) const
Returns i mod p and reduces the result into the appropriate bitwidth.
llvm::StringRef name() const
Definition Field.h:108
llvm::DynamicAPInt one() const
Returns 1 at the bitwidth of the field.
Definition Field.h:83
llvm::DynamicAPInt reduce(int i) const
Definition Field.h:97
llvm::DynamicAPInt felt(int i) const
Returns i as a signed field element.
Definition Field.h:77
llvm::DynamicAPInt reduce(const llvm::APInt &i) const
llvm::DynamicAPInt inv(const llvm::DynamicAPInt &i) const
Returns the multiplicative inverse of i in prime field p.
unsigned bitWidth() const
Definition Field.h:106
friend bool operator<(const Field &lhs, const Field &rhs)
Definition Field.h:119
llvm::SMTExprRef createSymbol(const llvm::SMTSolverRef &solver, const char *name) const
Create a SMT solver symbol with the current field's bitwidth.
Definition Field.h:111
static const Field & getField(llvm::StringRef fieldName)
Definition Field.h:61
llvm::DynamicAPInt inv(const llvm::APInt &i) const
static llvm::LogicalResult verifyFieldDefined(llvm::StringRef fieldName, EmitErrorFn errFn)
Search for a field with the given name, reporting an error if the field is not found.
Definition Field.cpp:60
static const Field & getField(llvm::StringRef fieldName, EmitErrorFn errFn)
Get a Field from a given field name string.
Field(Field &&) noexcept=default
static void addField(llvm::StringRef fieldName, const llvm::APInt &prime, EmitErrorFn errFn)
Add a new field to the set of available prime fields.
Definition Field.h:40
llvm::DynamicAPInt maxVal() const
Returns p - 1, which is the max value possible in a prime field described by p.
Definition Field.h:86
std::reference_wrapper< const Field > FieldRef
Typealias for a stable reference to a known Field.
Definition Field.h:152
llvm::function_ref< InFlightDiagnosticWrapper()> EmitErrorFn
Callback to produce an error diagnostic.
LogicalResult addSpecifiedFields(ModuleOp modOp)
Definition Field.cpp:177
llvm::SmallSet< FieldRef, 2 > FieldSet
Typealias for a set of Fields.
Definition Field.h:155
std::optional< std::reference_wrapper< const Field > > tryDetectSpecifiedField(mlir::Operation *root)
Try to detect a uniquely used field from the enclosing LLZK module.
mlir::LogicalResult collectFields(mlir::Operation *root, FieldSet &fields, bool silent=true)
Collects all the fields used in a circuit.
Definition Field.cpp:248