Obfuscating VHDL Code
Semantic Designs can construct custom obfuscators for virtually any source language as a part of the corresponding Source Formatter. This page contains VHDL sample code, its obfuscated version, and the generated obfuscation map.
VHDL Sample Code before Obfuscation
(This is the same formatted code shown on the VHDL Formatter example page)
USE work.multiplier_types.all;
USE work.bv_arithmetic.all;
USE std.textio.all;
ENTITY multiplier IS
PORT ( clk : in bit;
load : in bit;
multiplicand : in word;
multiply_by : in word;
ready : out bit;
product_low : inout word;
product_high : inout word );
END multiplier;
ARCHITECTURE mixed OF multiplier IS
COMPONENT reg_1
PORT ( clk : in bit;
load : in bit;
d : in bit;
q : out bit );
END COMPONENT;
COMPONENT shift_reg_word
PORT ( clk : in bit;
load : in bit;
shift : in bit;
clr : in bit;
d : in word;
d_s : in bit;
q : out word;
q_s : out bit );
END COMPONENT;
COMPONENT reg_word
PORT ( clk : in bit;
load : in bit;
d : in word;
q : out word);
END COMPONENT;
COMPONENT adder
PORT ( a : in word;
b : in word;
c_in : in bit;
s : out word;
c_out : out bit);
END COMPONENT;
COMPONENT and_word
PORT ( a : in bit;
b : in word;
z : out word);
END COMPONENT;
SIGNAL b : word;
SIGNAL b_or_0 : word;
SIGNAL partial_product : word;
SIGNAL c_in : bit;
SIGNAL c_out : bit;
SIGNAL c_to_p : bit;
SIGNAL p_to_a : bit;
SIGNAL p_and_c_load : bit;
SIGNAL shift : bit;
SIGNAL tied_0 : bit := '0';
ALIAS a_0 : bit IS product_low(0);
BEGIN -- mixed
a_reg : shift_reg_word
port map ( clk => clk,
load => load,
shift => shift,
clr => tied_0,
d => multiplicand,
d_s => p_to_a,
q => product_low,
q_s => open );
b_reg : reg_word
port map ( clk => clk,
load => load,
d => multiply_by,
q => b );
p_reg : shift_reg_word
port map ( clk => clk,
load => p_and_c_load,
shift => shift,
clr => load,
d => partial_product,
d_s => c_in,
q => product_high,
q_s => p_to_a );
carry_reg : reg_1
port map (clk => clk,
load => p_and_c_load,
d => c_out,
q => c_in );
b_gate : and_word
port map ( a => a_0,
b => b,
z => b_or_0 );
the_adder : adder
port map ( a => product_high,
b => b_or_0,
c_in => c_in,
s => partial_product,
c_out => c_out );
-----------------------------------------------------------------------------
-- Process: controller
-- Purpose: sequences register loading and shifting
-- Inputs: clk, load
-- Outputs: p_and_c_load, shift, ready
-----------------------------------------------------------------------------
controller : PROCESS
CONSTANT Tpd_clk_load : Time := 5 ns;
CONSTANT Tpd_clk_shift : Time := 5 ns;
CONSTANT Tpd_clk_ready : Time := 5 ns;
BEGIN -- PROCESS controller
p_and_c_load <= '0' after Tpd_Clk_Load;
shift <= '0' after Tpd_clk_shift;
ready <= '1' after Tpd_clk_ready;
WAIT on clk until clk = '1' and load = '1';
ready <= '0' after Tpd_clk_ready;
FOR cycle IN 1 to word_size LOOP
p_and_c_load <= '1' after Tpd_clk_load;
WAIT until clk = '1';
p_and_c_load <= '0' after Tpd_clk_load;
shift <= '1' after Tpd_clk_shift;
WAIT until clk = '1';
shift <= '0' after Tpd_clk_shift;
END LOOP; -- cycle
ready <= '1' after Tpd_clk_ready;
END PROCESS controller;
END mixed;
VHDL Code after Obfuscation
Notice that comments are gone, names have been scrambled. The obfuscator uses a special list provided by the user to define names that should be preserved, ensuring that public interfaces and accesses to public libraries remain valid. If you obfuscate a set of VHDL source files simultaneously, only the public symbols they collectively offer will be sensibly named in the source files.
use l.O.all;
use l.l1.all;
use std.textio.all;
entity multiplier is
port (clk: in bit;
load: in bit;
multiplicand: in word;
multiply_by: in word;
ready: out bit;
product_low: inout word;
product_high: inout word);
end multiplier;
architecture O0 of multiplier is
component ll1
port (clk: in bit;
load: in bit;
OO0: in bit;
l11: out bit);
end component;
component O00
port (clk: in bit;
load: in bit;
lll1: in bit;
OOO0: in bit;
OO0: in word;
l1l1: in bit;
l11: out word;
O0O0: out bit);
end component;
component ll11
port (clk: in bit;
load: in bit;
OO0: in word;
l11: out word);
end component;
component OO00
port (l111: in word;
O000: in word;
llll1: in bit;
OOOO0: out word;
l1ll1: out bit);
end component;
component O0OO0
port (l111: in bit;
O000: in word;
ll1l1: out word);
end component;
signal O000: word;
signal OO0O0: word;
signal l11l1: word;
signal llll1: bit;
signal l1ll1: bit;
signal O00O0: bit;
signal lll11: bit;
signal OOO00: bit;
signal lll1: bit;
signal l1l11: bit := '0';
alias O0O00: bit is product_low(0);
begin
ll111: O00 port map (clk => clk,load => load,lll1 => lll1,OOO0 => l1l11,OO0 => multiplicand,l1l1 => lll11,l11 => product_low,O0O0 => open );
OO000: ll11 port map (clk => clk,load => load,OO0 => multiply_by,l11 => O000);
l1111: O00 port map (clk => clk,load => OOO00,lll1 => lll1,OOO0 => load,OO0 => l11l1,l1l1 => llll1,l11 => product_high,O0O0 => lll11);
O0000: ll1 port map (clk => clk,load => OOO00,OO0 => l1ll1,l11 => llll1);
lllll1: O0OO0 port map (l111 => O0O00,O000 => O000,ll1l1 => OO0O0);
OOOOO0: OO00 port map (l111 => product_high,O000 => OO0O0,llll1 => llll1,OOOO0 => l11l1,l1ll1 => l1ll1);
l1lll1:
process is
constant O0OOO0: ll1ll1 := 5 OO0OO0;
constant l11ll1: ll1ll1 := 5 OO0OO0;
constant O00OO0: ll1ll1 := 5 OO0OO0;
begin
OOO00 <= '0' after O0OOO0;
lll1 <= '0' after l11ll1;
ready <= '1' after O00OO0;
wait on clk until clk = '1' and load = '1';
ready <= '0' after O00OO0;
for lll1l1 in 1 to OOO0O0
loop
OOO00 <= '1' after O0OOO0;
wait until clk = '1';
OOO00 <= '0' after O0OOO0;
lll1 <= '1' after l11ll1;
wait until clk = '1';
lll1 <= '0' after l11ll1;
end loop;
ready <= '1' after O00OO0;
end process l1lll1;
end O0;
Obfuscated Symbol Cross Reference
The obfuscator produces a cross reference mapping obfuscated symbols to the orginal symbols, so that obfuscated code in the field can still be decoded if necessary. In fact, by reversing this map, the obfuscator can unobfuscate the code (of course, it cannot restore the comments).
### Obfuscated Identifiers ### a -> l111 a_0 -> O0O00 a_reg -> ll111 adder -> OO00 and_word -> O0OO0 b -> O000 b_gate -> lllll1 b_or_0 -> OO0O0 b_reg -> OO000 bv_arithmetic -> l1 c_in -> llll1 c_out -> l1ll1 c_to_p -> O00O0 carry_reg -> O0000 clr -> OOO0 controller -> l1lll1 cycle -> lll1l1 d -> OO0 d_s -> l1l1 mixed -> O0 multiplier_types -> O ns -> OO0OO0 p_and_c_load -> OOO00 p_reg -> l1111 p_to_a -> lll11 partial_product -> l11l1 q -> l11 q_s -> O0O0 reg_1 -> ll1 reg_word -> ll11 s -> OOOO0 shift -> lll1 shift_reg_word -> O00 the_adder -> OOOOO0 tied_0 -> l1l11 time -> ll1ll1 tpd_clk_load -> O0OOO0 tpd_clk_ready -> O00OO0 tpd_clk_shift -> l11ll1 word_size -> OOO0O0 work -> l z -> ll1l1 ### Preserved Identifiers ### bit -> bit clk -> clk load -> load multiplicand -> multiplicand multiplier -> multiplier multiply_by -> multiply_by product_high -> product_high product_low -> product_low ready -> ready std -> std textio -> textio word -> word
Copyright © 1995-2008 Semantic Designs, Incorporated
DMS and "Design Maintenance System" are registered trademarks of Semantic Designs, Inc.
The SD logo and "Semantic Designs" are registered service marks of Semantic Designs, Inc.
CloneDR, PARLANSE and Thicket are trademarks of Semantic Designs, Inc.
The OMG logo is a registered trademark of the Object Management Group, Inc. in the United States and other countries.
To view our Privacy Policy, click here
Comments or problems: webmaster@semdesigns.com
