Ada - Sensible code structure for SHA3 implementation - ada

I'm using the SHA3 specification as a learning example for the Ada programming language.
The spec contains a family of data structures call Permutations, there are seven of these and they differ only by being able to handle different amounts of data. They contain a three-dimensional "State Array" where the first two dimensions are always mod 5 and the third dimension is mod N, where N is limited to these few values: 25, 50, 100, 200, 400, 800 and 1600.
I'd normally think to use generics to make the distinction between each package variation, but the difference is a number, and not a type.
How might I sensibly design my package / record types?
The only way I can think of doing this is to simply make a set of explicit types...
package Perm_25 is...
package Perm_50 is...
package Perm_100 is...
package Perm_200 is...
package Perm_400 is...
package Perm_800 is...
package Perm_1600 is...
Clearly that is nonsensical because it's laborious and requires me to duplicate a lot of code, which would invite inconsistencies.
Also I'm not convinced that OOP would help here because the types really aren't different apart from some array dimensions.
How should I approach this problem?
EDIT: Thanks to user #flyx for the tip to use a Static_Predicate subtype and a discriminated record type. Using that advice I have managed to get the following code to compile...
package body SHA3 is
subtype Perm_w_Coeff_Type is Positive
with Static_Predicate
=> Perm_w_Coeff_Type in 1 | 2 | 4 | 8 | 16 | 32 | 64;
subtype Perm_l_Coeff_Type is Natural range 0 .. 6;
type State_Array_Type is array (Natural range <>, Natural range <>, Natural range <>) of Boolean;
-- (see FIPS202 section 3)
type KECCAK_p_Permutation (bPW : b_Permutation_Width; numRounds : Positive; W_Coeff : Perm_w_Coeff_Type) is
record
b : b_Permutation_Width := bPW;
-- initialise w based on a lookup table using b as its index
-- (see FIPS202 section 3.1, table 1)
w : Perm_w_Coeff_Type := (
case bPW is
when 25 => 1,
when 50 => 2,
when 100 => 4,
when 200 => 8,
when 400 => 16,
when 800 => 32,
when 1600 => 64
);
-- initialise l based on a lookup table using b as its index
-- (see FIPS202 section 3.1, table 1)
l : Perm_l_Coeff_Type := (
case bPW is
when 25 => 0,
when 50 => 1,
when 100 => 2,
when 200 => 3,
when 400 => 4,
when 800 => 5,
when 1600 => 6
);
n_sub_r : Positive := numRounds;
State_Array : State_Array_Type (0 .. 4, 0 .. 4, 0 .. W_Coeff);
end record;
procedure Run is
begin
null;
end Run;
end SHA3;

subtype Third_Dimension_Type is Natural with
Static_Predicate => Third_Dimension_Type in 25 | 50 | 100 | 200 | 400 | 800 | 1600;
I don't know what you mean by „the first two dimensions are always mod 5“, but assuming you mean they have 5 entries, the resulting data type would the be something like:
type Permutation (Third_Dimension : Third_Dimension_Type) is record
State : array (1..5, 1..5, 1..Third_Dimension) of Item_Type;
end record;
Note that you cannot specify an array type that takes two discrete ranges and one indefinite range (e.g. Third_Dimension_Type range <>), so you need to use a discriminated record instead.

I haven't gone for the detail of your question, but I'm answering something that caught my eye: you say you can't use generics because the parameter that changes isn't a type. However, you can parameterize generics with values (not saying that's the best approach in this case, but that you can do it):
generic
Foo : Integer := 5; -- Or any other type.
package Bar is ...

Related

Simple Go Pointer Explaination

Im working through a Go Ebook.
Here we are creating an array of pointers as so:
sampleArray := [5]*int{0: new(int), 1: new(int)}
As you can see index 0 and index 1 of sampleArray contain initialized integers whereas the remaining indexes contain uninitialized integers.
Then they do the following operation:
*sampleArray[0] = 10
*sampleArray[1] = 20
With that, the values of sampleArray should be:
[0] => address (integer pointer) -> 10
[1] => address (integer pointer) -> 20
[2] => nil (integer pointer)
[3] => nil (integer pointer)
[4] => nil (integer pointer)
My question is, why do we do this:
*sampleArray[0] = 10
*sampleArray[1] = 20
And not this:
sampleArray[0] = 10
sampleArray[1] = 20
To me it looks like we are assigning a value to a pointer which points to another pointer. Shouln't we be assigning the value to the actual memory reference?
Why not then?
&sampleArray[0] = 10
&sampleArray[1] = 20
Im extremely new to pointers so please any thourough assistance would be helpful
This is actually a good question.
The dereferencing operator * has a lower precedence than array access (which in C is equivalent to pointer deref). So *a[x] in Go means "dereference a[x]" and not "dereference a and take element x".
Hope this clarifies things.

How to use predicate exactly in MiniZinc

New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.

Check if an argument is a dictionary or not in Tcl

I want have a proc which does something if its' argument is a Tcl 8.5 and above dictionary or not.
I could not find anything straightforward from Tcl dict command.
The code which I could get working is:
proc dict? {dicty} {
expr { [catch { dict info $dicty } ] ? 0 : 1 }
}
Is there anything w/o using catch, something built in?Thanks.
You can test if a value is a dictionary by seeing if it is a list and if it has an even number of elements; all even length lists may be used as dictionaries (though many are naturally not canonical dictionaries because of things like duplicate keys).
proc is-dict {value} {
return [expr {[string is list $value] && ([llength $value]&1) == 0}]
}
You can peek at the actual type in Tcl 8.6 with tcl::unsupported::representation but that's not advised because things like literals are converted to dictionaries on the fly. The following is legal, shows what you can do, and shows the limitations (
% set value {b c d e}
b c d e
% tcl::unsupported::representation $value
value is a pure string with a refcount of 4, object pointer at 0x1010072e0, string representation "b c d e"
% dict size $value
2
% tcl::unsupported::representation $value
value is a dict with a refcount of 4, object pointer at 0x1010072e0, internal representation 0x10180fd10:0x0, string representation "b c d e"
% dict set value f g;tcl::unsupported::representation $value
value is a dict with a refcount of 2, object pointer at 0x1008f00c0, internal representation 0x10101eb10:0x0, no string representation
% string length $value
11
% tcl::unsupported::representation $value
value is a string with a refcount of 2, object pointer at 0x1008f00c0, internal representation 0x100901890:0x0, string representation "b c d e f g"
% dict size $value;tcl::unsupported::representation $value
value is a dict with a refcount of 2, object pointer at 0x1008f00c0, internal representation 0x1008c7510:0x0, string representation "b c d e f g"
As you can see, types are a bit slippery in Tcl (by design) so you're strongly advised to not rely on them at all.
Your approach is flawed because Tcl has dynamic type system where the actual type of a value is able to morph dynamically and depends on the commands applied to it—observe:
$ tclsh
% info pa
8.5.11
% dict info {a b}
1 entries in table, 4 buckets
number of buckets with 0 entries: 3
number of buckets with 1 entries: 1
number of buckets with 2 entries: 0
number of buckets with 3 entries: 0
number of buckets with 4 entries: 0
number of buckets with 5 entries: 0
number of buckets with 6 entries: 0
number of buckets with 7 entries: 0
number of buckets with 8 entries: 0
number of buckets with 9 entries: 0
number of buckets with 10 or more entries: 0
average search distance for entry: 1.0
% llength {a b}
2
% string len {a b}
3
%
As you can see, the same value {a b} is a dictionary, a list and a string: in each case, the value acquires its "real" type in the very moment a Tcl command expecting a value of certain type converts the "default" type of the value, which is string, to the one the command operates on.
You should understand by now that trying to make a call dict? {a b} has little sence as the value {a b} is a perfect dict as well as a perfect list as well as a perfect string, and it could be, say, a perfect tuple if there are custom commands in the current interpreter working on tuples (lists of fixed length).
Hence the real approach you should take is to just blindly use dict command on those values passed to your commands you expect to contain dictionaries. If a user will manage to pass to your command something which is not interpretable as a dictionary, the dict command will fail, and that's a good thing to do as such an error is not really recoverable (it's a programming error).
Any attempt to count on a value's specific type is going again the grain of the very idea of the Tcl's implicit/dynamic typing. It's even true for the Tcl C API.
If you really meant to ask how to be sure the current Tcl version supports dict command, and not about the type of a particular value, test the Tcl's version somewhere at startup and save this as a flag, like this:
set hasDicts [expr {[package vcompare [info tclversion] 8.5] >= 0}]
But note that your code relying on the hasDicts value is now in some gray zone because if the user is not supplying you values you process with the dict command then what command you use to process them?
Please also note that the dict command can be added to a Tcl 8.4 interpreter in the form of the loadable module (see this).

ERROR: `*` has no method matching *(::Variable)

I wrote the following code:
using JuMP
m = Model()
const A =
[ :a0 ,
:a1 ,
:a2 ]
const T = [1:5]
const U =
[
:a0 => [9 9 9 9 999],
:a1 => [11 11 11 11 11],
:a2 => [1 1 1 1 1]
]
#defVar(m, x[A,T], Bin)
#setObjective(m, Max, sum{sum{x[i,j] * U[i,j], i=A}, j=T} )
print(m)
status = solve(m)
println("Objective value: ", getObjectiveValue(m))
println("x = ", getValue(x))
When I run it I get the following error
ERROR: `*` has no method matching *(::Variable)
in anonymous at /home/username/.julia/v0.3/JuMP/src/macros.jl:71
in include at ./boot.jl:245
in include_from_node1 at loading.jl:128
in process_options at ./client.jl:285
in _start at ./client.jl:354
while loading /programs/julia-0.2.1/models/a003.jl, in expression starting on line 21
What's the correct way of doing this?
As the manual says:
There is one key restriction on the form of the expression in the second case: if there is a product between coefficients and variables, the variables must appear last. That is, Coefficient times Variable is good, but Variable times Coefficient is bad
Let me know if there is another place I could put this that would have helped you out.
This situation isn't desirable but unfortunately we haven't got a good solution yet that retains the fast model construction capabilities of JuMP.
I believe the problem with U is that it is a dictionary of arrays, thus you first need to index into the dictionary to return the correct array, then index into the array. JuMP's variables have more powerful indexing, so allow you to do it in one set of [].
I resolved my problem: constants must preceed variables as I read somewhere, moreover it seems that an array of constants must be used as an array of arrays while variables can be used as matrices.
Here's the correct line:
#setObjective(m, Max, sum{sum{U[i][j]*x[i,j], i=A}, j=T} )

How do you use matrices in Nimrod?

I found this project on GitHub; it was the only search term returned for "nimrod matrix". I took the bare bones of it and changed it a little bit so that it compiled without errors, and then I added the last two lines to build a simple matrix, and then output a value, but the "getter" function isn't working for some reason. I adapted the instructions for adding properties found here, but something isn't right.
Here is my code so far. I'd like to use the GNU Scientific Library from within Nimrod, and I figured that this was the first logical step.
type
TMatrix*[T] = object
transposed: bool
dataRows: int
dataCols: int
data: seq[T]
proc index[T](x: TMatrix[T], r,c: int): int {.inline.} =
if r<0 or r>(x.rows()-1):
raise newException(EInvalidIndex, "matrix index out of range")
if c<0 or c>(x.cols()-1):
raise newException(EInvalidIndex, "matrix index out of range")
result = if x.transposed: c*x.dataCols+r else: r*x.dataCols+c
proc rows*[T](x: TMatrix[T]): int {.inline.} =
## Returns the number of rows in the matrix `x`.
result = if x.transposed: x.dataCols else: x.dataRows
proc cols*[T](x: TMatrix[T]): int {.inline.} =
## Returns the number of columns in the matrix `x`.
result = if x.transposed: x.dataRows else: x.dataCols
proc matrix*[T](rows, cols: int, d: openarray[T]): TMatrix[T] =
## Constructor. Initializes the matrix by allocating memory
## for the data and setting the number of rows and columns
## and sets the data to the values specified in `d`.
result.dataRows = rows
result.dataCols = cols
newSeq(result.data, rows*cols)
if len(d)>0:
if len(d)<(rows*cols):
raise newException(EInvalidIndex, "insufficient data supplied in matrix constructor")
for i in countup(0,rows*cols-1):
result.data[i] = d[i]
proc `[][]`*[T](x: TMatrix[T], r,c: int): T =
## Element access. Returns the element at row `r` column `c`.
result = x.data[x.index(r,c)]
proc `[][]=`*[T](x: var TMatrix[T], r,c: int, a: T) =
## Sets the value of the element at row `r` column `c` to
## the value supplied in `a`.
x.data[x.index(r,c)] = a
var m = matrix( 2, 2, [1,2,3,4] )
echo( $m[0][0] )
This is the error I get:
c:\program files (x86)\nimrod\config\nimrod.cfg(36, 11) Hint: added path: 'C:\Users\H127\.babel\libs\' [Path]
Hint: used config file 'C:\Program Files (x86)\Nimrod\config\nimrod.cfg' [Conf]
Hint: system [Processing]
Hint: mat [Processing]
mat.nim(48, 9) Error: type mismatch: got (TMatrix[int], int literal(0))
but expected one of:
system.[](a: array[Idx, T], x: TSlice[Idx]): seq[T]
system.[](a: array[Idx, T], x: TSlice[int]): seq[T]
system.[](s: string, x: TSlice[int]): string
system.[](s: seq[T], x: TSlice[int]): seq[T]
Thanks you guys!
I'd like to first point out that the matrix library you refer to is three years old. For a programming language in development that's a lot of time due to changes, and it doesn't compile any more with the current Nimrod git version:
$ nimrod c matrix
...
private/tmp/n/matrix/matrix.nim(97, 8) Error: ']' expected
It fails on the double array accessor, which seems to have changed syntax. I guess your attempt to create a double [][] accessor is problematic, it could be ambiguous: are you accessing the double array accessor of the object or are you accessing the nested array returned by the first brackets? I had to change the proc to the following:
proc `[]`*[T](x: TMatrix[T], r,c: int): T =
After that change you also need to change the way to access the matrix. Here's what I got:
for x in 0 .. <2:
for y in 0 .. <2:
echo "x: ", x, " y: ", y, " = ", m[x,y]
Basically, instead of specifying two bracket accesses you pass all the parameters inside a single bracket. That code generates:
x: 0 y: 0 = 1
x: 0 y: 1 = 2
x: 1 y: 0 = 3
x: 1 y: 1 = 4
With regards to finding software for Nimrod, I would like to recommend you using Nimble, Nimrod's package manager. Once you have it installed you can search available and maintained packages. The command nimble search math shows two potential packages: linagl and extmath. Not sure if they are what you are looking for, but at least they seem more fresh.

Resources