Skip to content

Tutorial

Ushitora Anqou edited this page Sep 3, 2021 · 2 revisions

Write a circuit you want to run in Chisel3 like this (test/test-div-8bit.scala):

import chisel3._

class Divider8bitPort extends Bundle {
  val in_a = Input(UInt(8.W))
  val in_b = Input(UInt(8.W))
  val out = Output(UInt(8.W))
}

class Divider8bit extends Module {
  val io = IO(new Divider8bitPort)

  io.out := io.in_a / io.in_b
}

object Elaborate extends App {
  chisel3.Driver.execute(args, () => new Divider8bit())
}

Compile this code with sbt (Chisel's tool) to Verilog file. Then compile it to net list in JSON with Yosys, and again compile it to DAG in JSON with Iyokan-L1. test/test-div-8bit.json is the one after all conversions. (FIXME: We don't have to use Iyokan-L1 here as of d61d8e3.)

Write a configuration file in TOML, which includes specification of inputs/outputs (test/test-div-8bit.toml):

# Add DAG's JSON file as a module.
[[file]]
type = "iyokanl1-json"
path = "test-div-8bit.json"  # Compiled JSON's path
name = "core"

# Connect the module and Iyokan's core ports.
[connect]
"core/reset" = "@reset"
"core/io_in_a[0:7]" = "@A[0:7]"
"core/io_in_b[0:7]" = "@B[0:7]"
"@out[0:7]" = "core/io_out[0:7]"

Now we will run this circuit with test inputs. The inputs have to be 'packed' into a single file with iyokan-packet. Write another TOML file like this (test/test05.in):

[[bits]]
name = "A"      # To input port 'A'
size = 8        # 8-bit-wide (1-byte-wide) integer
bytes = [159]   # Input 159

[[bits]]
name = "B"      # To input port 'B'
size = 8        # 8-bit-wide (1-byte-wide) integer
bytes = [53]    # Input 53

Then convert this TOML file into 'packet' with iyokan-packet:

$ iyokan-packet toml2packet --in test/test05.in --out request.plain.packet

Okay. Run Iyokan in plaintext mode with this packet as input to check it's correct:

$ iyokan plain --blueprint test/test-div-8bit.toml \
               -i request.plain.packet -o result.plain.packet -c 1

The result will be stored into result.plain.packet. Let's inspect its content:

$ iyokan-packet packet2toml --in result.plain.packet
rom = []
cycles = 1
ram = []
bits = [
{bytes=[3],size=8,name="out"},
]
Done. (0 seconds)

bytes=[3] means the output of the circuit is 3, which is exactly the same as 159/53.

Now, we will run Iyokan with the same but encrypted packet as input. First, generate a secret key to encrypt the data:

$ iyokan-packet genkey --type tfhepp --out secret.key

Next, encrypt the packet:

$ iyokan-packet genbkey --in secret.key --out bootstrapping.key
$ iyokan-packet enc --key secret.key --in request.plain.packet --out request.enc.packet

Finally, run Iyokan with it:

# Use option `--enable-gpu` if your machine has a NVIDIA GPU such as V100.
$ iyokan tfhe --blueprint test/test-div-8bit.toml --bkey bootstrapping.key \
              -i request.enc.packet -o result.enc.packet -c 1

Decrypt the result to get its content:

$ iyokan-packet dec --key secret.key --in result.enc.packet --out result.plain.packet
$ iyokan-packet packet2toml --in result.plain.packet
rom = []
cycles = 1
ram = []
bits = [
{bytes=[3],size=8,name="out"},
]
Done. (0 seconds)

Finally we could get the same consequence as that in plaintext using ciphertext!

Clone this wiki locally