From f6a8c0cdacd78983dd7ce5b04f07cba7613cec52 Mon Sep 17 00:00:00 2001 From: Minyong Li <ml10g20@soton.ac.uk> Date: Tue, 15 Jun 2021 19:55:54 +0100 Subject: [PATCH] core: impl ChaChaBlockFunction{Test} --- .../ecs/can/core/ChaChaBlockFunction.scala | 23 ++++++ .../ac/soton/ecs/can/core/ColumnRound.scala | 23 ++++++ .../ac/soton/ecs/can/core/DiagonalRound.scala | 23 ++++++ .../ac/soton/ecs/can/core/DoubleRound.scala | 24 ++++++ .../can/core/ChaChaBlockFunctionTest.scala | 75 +++++++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunction.scala create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/ColumnRound.scala create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/DiagonalRound.scala create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/DoubleRound.scala create mode 100644 src/test/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunctionTest.scala diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunction.scala b/src/main/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunction.scala new file mode 100644 index 0000000..e8f2afc --- /dev/null +++ b/src/main/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunction.scala @@ -0,0 +1,23 @@ +package uk.ac.soton.ecs.can.core + +import chisel3._ + +class ChaChaBlockFunction extends Module { + val io = IO(new Bundle { + val muxIn = Input(Bool()) + val in = Input(Vec(16, UInt(32.W))) + val out = Output(Vec(16, UInt(32.W))) + }) + + val initialState = Reg(Vec(16, UInt(32.W))) + val doubleRound = Module(new DoubleRound(regBetweenRounds = true)) + val doubleRoundState = Reg(Vec(16, UInt(32.W))) + + initialState := io.in + doubleRound.io.in := Mux(io.muxIn, initialState, doubleRoundState) + doubleRoundState := doubleRound.io.out + + val addedState = doubleRoundState.zip(initialState).map(t => t._1 + t._2) + + io.out := addedState +} diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/ColumnRound.scala b/src/main/scala/uk/ac/soton/ecs/can/core/ColumnRound.scala new file mode 100644 index 0000000..367d125 --- /dev/null +++ b/src/main/scala/uk/ac/soton/ecs/can/core/ColumnRound.scala @@ -0,0 +1,23 @@ +package uk.ac.soton.ecs.can.core + +import chisel3._ + +class ColumnRound extends Module { + val io = IO(new Bundle { + val in = Input(Vec(16, UInt(32.W))) + val out = Output(Vec(16, UInt(32.W))) + }) + + Seq( + Seq(0, 4, 8, 12), + Seq(1, 5, 9, 13), + Seq(2, 6, 10, 14), + Seq(3, 7, 11, 15) + ).foreach { roundWires => + val quarterRound = Module(new QuarterRound) + roundWires.zipWithIndex.foreach { roundWire => + quarterRound.io.in(roundWire._2) := io.in(roundWire._1) + io.out(roundWire._1) := quarterRound.io.out(roundWire._2) + } + } +} diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/DiagonalRound.scala b/src/main/scala/uk/ac/soton/ecs/can/core/DiagonalRound.scala new file mode 100644 index 0000000..8e93499 --- /dev/null +++ b/src/main/scala/uk/ac/soton/ecs/can/core/DiagonalRound.scala @@ -0,0 +1,23 @@ +package uk.ac.soton.ecs.can.core + +import chisel3._ + +class DiagonalRound extends Module { + val io = IO(new Bundle { + val in = Input(Vec(16, UInt(32.W))) + val out = Output(Vec(16, UInt(32.W))) + }) + + Seq( + Seq(0, 5, 10, 15), + Seq(1, 6, 11, 12), + Seq(2, 7, 8, 13), + Seq(3, 4, 9, 14) + ).foreach { roundWires => + val quarterRound = Module(new QuarterRound) + roundWires.zipWithIndex.foreach { roundWire => + quarterRound.io.in(roundWire._2) := io.in(roundWire._1) + io.out(roundWire._1) := quarterRound.io.out(roundWire._2) + } + } +} diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/DoubleRound.scala b/src/main/scala/uk/ac/soton/ecs/can/core/DoubleRound.scala new file mode 100644 index 0000000..1639139 --- /dev/null +++ b/src/main/scala/uk/ac/soton/ecs/can/core/DoubleRound.scala @@ -0,0 +1,24 @@ +package uk.ac.soton.ecs.can.core + +import chisel3._ + +class DoubleRound(regBetweenRounds: Boolean) extends Module { + val io = IO(new Bundle { + val in = Input(Vec(16, UInt(32.W))) + val out = Output(Vec(16, UInt(32.W))) + }) + + val betweenRounds = + if (regBetweenRounds) + Reg(Vec(16, UInt(32.W))) + else + Wire(Vec(16, UInt(32.W))) + + val columnRound = Module(new ColumnRound) + val diagonalRound = Module(new DiagonalRound) + + columnRound.io.in := io.in + betweenRounds := columnRound.io.out + diagonalRound.io.in := betweenRounds + io.out := diagonalRound.io.out +} diff --git a/src/test/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunctionTest.scala b/src/test/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunctionTest.scala new file mode 100644 index 0000000..9c7dc83 --- /dev/null +++ b/src/test/scala/uk/ac/soton/ecs/can/core/ChaChaBlockFunctionTest.scala @@ -0,0 +1,75 @@ +package uk.ac.soton.ecs.can.core + +import org.scalatest._ +import chiseltest._ +import chisel3._ + +class ChaChaBlockFunctionTest extends FlatSpec with ChiselScalatestTester { + + private val rfc8439232TestVectorIn = Seq( + "h61707865".U(32.W), + "h3320646e".U(32.W), + "h79622d32".U(32.W), + "h6b206574".U(32.W), + "h03020100".U(32.W), + "h07060504".U(32.W), + "h0b0a0908".U(32.W), + "h0f0e0d0c".U(32.W), + "h13121110".U(32.W), + "h17161514".U(32.W), + "h1b1a1918".U(32.W), + "h1f1e1d1c".U(32.W), + "h00000001".U(32.W), + "h09000000".U(32.W), + "h4a000000".U(32.W), + "h00000000".U(32.W) + ) + private val rfc8439232TestVectorOut = Seq( + "he4e7f110".U(32.W), + "h15593bd1".U(32.W), + "h1fdd0f50".U(32.W), + "hc47120a3".U(32.W), + "hc7f4d1c7".U(32.W), + "h0368c033".U(32.W), + "h9aaa2204".U(32.W), + "h4e6cd4c3".U(32.W), + "h466482d2".U(32.W), + "h09aa9f07".U(32.W), + "h05d7c214".U(32.W), + "ha2028bd9".U(32.W), + "hd19c12b5".U(32.W), + "hb94e16de".U(32.W), + "he883d0cb".U(32.W), + "h4e3c50a2".U(32.W) + ) + + it should "compute RFC8439 2.3.2 test vector correctly" in { + test(new ChaChaBlockFunction) { c => + c.io.in.zip(rfc8439232TestVectorIn).foreach { t => + t._1.poke(t._2) + } + + // Shift inputs into the initial state register + c.clock.step() + + // Select the initial state register as the input to the 2-round circuit + c.io.muxIn.poke(true.B) + + // Shift the 2-rounded state to the round register + c.clock.step(2) + + // Select the round register as the input to the 2-round circuit + c.io.muxIn.poke(false.B) + + // Depending on the ChaCha variant and the pipeline configuration, wait + // for the correct time for the correct result. Note that one 2-round has + // been processed in the above steps. + c.clock.step(19) + + c.io.out.zip(rfc8439232TestVectorOut).foreach { t => + t._1.expect(t._2) + } + } + } + +} -- GitLab