CodeLock 60 - the ultimate combination lock

The proposed code lock can drive various electromechanical locking mechanisms directly. Whereas, in idle state, the appliance does not consume any power at all. This allows for independent operation from batteries or rechargeables. For uncompromising safety, decimal keys may be up to 60 digits. As a matter of fact, all hardware and software details have been fully disclosed.






Make your own





Electronic code locks, any ideas?

Well there's lots of professional or semi-professional security stuff advertised. Professional in terms of pricing, and missing all relevant details on hardware and source codes. Oh, we understand, it's closed-source! Customers should simply believe in unsubstantiated security claims unless they did some serious (but sometimes 'illegal') reverse-engineering, only to prove that there are no backdoors implemented. How can it be that manufacturers still come away with such "security-by-obscurity" crap? I use to say: No transparency, no buy!

Kits and pre-assembled devices? Can't be worse. Most of them do simply ignore basic concepts of security, gaping wide open for the oldest of old-school electronic lockpicking methods... Keypad and electronics on one and the same PCB? Is this a typo or does the fancy electronics consume about several milliamperes in the standby state? Oh, we need permanent power supply? Are you kiddin'?

Obviously, there's lots of DIY instructables on the Inet. Here we may actually find full range of moderate to bad examples.
Cardinal points of failure: No spatial separation between input device and code checking logic; code-entry and code-checking at the same time; cumbersome operation; vulnerable by tapping keypad lines; fat microcontrollers and bulky programming; unacceptably high idle current; susceptibility for RF-flooding-/Power-analysis-/Phreaking attack; mindless LED/LCD-stuff; multi-user stuff irrelevant for most private applications; superfluous clock functionality; use of obsolete or exotic components; lengthy bachelor-thesis-blabber; detached from reality...

Well, let's have a look on how to make a really safe electronic code lock!

Project "CodeLock"

  1. A code lock how it's supposed to be. Only input device is a decimal keypad. This code lock will energize a motor/solenoid based mechanism to perform "door-open", after the right code has been entered. If not, the "door-close" functionality will be triggered, as with other keys pressed. Even the code change is rather straightforward on this lock. In particular, it does not require brainfuckin' input sequences. And we will do without mindless LCD or LED stuff. Nobody really needs a display to indicate that a key is to be entered or the door has been unlocked. A single LED will be sufficient to indicate that the system has just been energized. Of course, my CodeLock provides optional acoustic feedback, but the beeps are not prerequisite for successfull operation.

  2. Autonomous operation: The CodeLock circuit must be activated by pressing asterisk [*] key at first. In the deactivated state, the electronics will actually be disconnected from the power supply. Its quiescent current is negligible and the whole appliance may be powered by batteries or rechargeables.
    It is even possible to feed both, electronics and electromechanics, from one and the same battery. Such battery must be strong enough to energize an electro motor, but anyway, there will only be comparably short periods of peak power. Most of the time, the CodeLock is being deactivated and no current is drawn from the battery. This minimizes risk of deep discharge which could otherwise brick some electronic code lock. Of course, with systems under heavy load, some backup and permanently recharged battery technology would be an option to improve reliability.

  3. Control capabilities: Power switching is done by two (monostable) relays, capable of energizing different types of  DC-motors in CW/CCW mode or bistable relays for load control of up to 4 Amps.
    For clarification: Present circuit does NOT perform electric isolation, since its initial concept was to provide an independent electronic lock to be simply operated by one single battery, e.g. for strongboxes and safes.
    Yet, in a customized setup with modified circuit firmware it would be easy to implement electric isolation. My recommendation is yet to leave the circuit of CodeLock unchanged and then use its switched DC to selectively drive one or two "downstream" relays selected by a prediode, or maybe some bistable relays etc. Generally this method enables control of higher current and considerable AC load.

  4. The CodeLock Hardware was designed for an energy-efficient and reliable operation with batteries. Heart of this CodeLock is the AVR ATtiny2313, which has proven its longevity in many other projects.

  5. The suggested Firmware named "CodeLock 60" could administer two decimal access codes of up to 60 digits (!) each. One code is for daily use ("User-Code"), another code is destined to regain access to the CodeLock, if the User-Code got "lost" ("Master-Code"). It has to be mentioned, that there is NO hardcoded "factory settings" or "maintenance code" existing. The Master-Code in this CodeLock is the one and only "backdoor" and it remains a 100 percent under the control of the legitimate user.

  6. A Software utility for the PC platform could help with decimal random generation of variable strength and storage of codes. Along with a human-readable text file, the programme also provides binary and hexfiles that may be used for direct programming of the EEPROM section in the Microcontroller.

  7. Alarm systems and home automation: Integration of CodeLock into networked/security environment was not intended from original concept but you are free to do so by utilizing existing signals to arm/disarm alarm systems and/or do some firmware mods that provide additional signalling on some of the spare I/O's of the microcontroller.

  8. All details of this project are being fully disclosed under Creative Commons.


Circuit plan

My DIY CodeLock concept offers serious security features and versatile actuator control with no backdoors.
You can download all technical documentation here.

Top | Index


General: Press [*] to activate the lock-electronics. Legitimate user can then input the code of up to 60 digits and finish code entry by pressing the "number sign" [#].
CodeLock will then check the code just entered and, if correct, energize some electromagnet/electromotor for release of a locking-mechanics. Yet, if the code entered was not correct, then CodeLock will be blocked for at least 8 seconds. This effectively inhibits multiple attempts of "brute-forcing" the correct combination.
The solution utilizes position switches ("end-switches") to ensure that the door/bolt is completely extended, rejected. This feedback is quite useful for an energy-efficient operation, but is not an obligation. Get more information regarding the logic control in my Operating instructions and the details of the Firmware. Right here, we will focus on electronic details.

Power supply: As already mentioned, one fundamental of this code-lock-concept was minimum power consumption that will allow continued operation on batteries. These are required to deliver higher currents only for the short time when electromotors or solenoids are being energized. The "Standby" state of the appliance is rather a switched off state. The circuit will have no measurable operating current then.
And that's how it works: The PNP transistor T3 (BC327) is utilized as an electronic switch between battery and logic. Since the base terminal of T3 is being held on positive voltage by R7 (47 k), i.e. emitter voltage level, the transistor won't become conductive and is effectively "switched off".
However, if the user presses "asterisk" key on the numeric keypad, a base current of several milliamps will flow through R10, keypad contacts X1-Y4 and R23 (several milliamps) to ground. Now T3 will forward unstabilized positive current from the battery to voltage regulator VR1 (78L05) and logic parts.
The microcontroller itself can now secure its power supply by rising portline PD1 to switch T4 and thus pulling the base of T3 permanently to ground.
After the programe had done its job, or time-out of the CodeLock application has expired, the controller can also detach itself from power supply by T4/T3. After this, the lock may be re-energized by pressing [*].
VR1 is a conventional linear regulator (78L05) that provides pretty good protection against voltage drops and peaks and noise caused by dc-motor. However, this type of regulator will draw a quiescent current of no less than 5 mA (see data sheet). This is no problem in here, since we always disconnect the whole microcontroller plus stabilizer from the battery.
To enable programming of the microcontroller via ISP-intermediate socket right on-board, we may short X6 (MASTER KEY) by a simple jumper. This will provide permanent electric power to the logic part.
Additionally, this input may be used for a "Master-Button" that allows to open (and close) the locking system from the "other side" (inside the domicile).
The fact, that motor voltage supply and logic control supply are provided by the same battery, is way not so problematic. Some testing in a 12-V-system showed up, that the controller won't even crash if the load is a "mechanically locked DC motor". If the shunt resistors (see below) are not too low impedance, there should always be enough voltage provided to ensure safe operation of the controller. Should however, the battery voltage collapse and fall below the minimum voltage for the controller (Brown-out detector), then a Reset is automatically applied and it's a matter of fact that the circuit was designed such way that power-drop in the logic part will cause safe switch-off of the load.
Relay energizing voltage depends on battery voltage. Battery voltage depends on motor voltage. Consequently for this CodeLock circuit, any operating voltage in the range of 6 to 24 V is safe.

Microcontroller: All control lies within IC1, an AVR-ATtiny2313 microcontroller. The micro doesn't have to calculate very fast, so it shall be fed either with internally generated clock of 500 kHz (derived from 4-MHz-RCO and division by 8) or internal 128 kHz that are provided by the Watchdog-Oscillator that will be needed anyway.

H-Bridge output with motor brake feature (X2): Re1 and Re2 present a classic H-bridge that powers motor terminals X2a and X2b with positive or negative current of (full) supply voltage. Electromotors or solenoids should be connected ground-free (floating) to the CodeLock circuit, and sufficient filtering (chokes, capacitors) is recommended for DC-motors. The resistors R1 and R2 in series with supply voltage are intended to limit maximum load current, particularly in case of a locking mechanism being blocked or motor terminals even short circuit.
Dimensioning of R1 and R2 must consider that worst-case fault current should not excite 4 Amps with respect to the maximum current specifications for this type of relays. On the other hand, the motor should be provided with sufficient starting current even inspite of a
weak battery. For many small and medium motors in question, the values of R1+R2 are ranging between 2...10 Ohms.
It is plain to see that, when in idle/unpowered state, both terminals X2a and X2b are permanently tied to GND. This provides for a "motor brake" that will stay in force even with battery power switched off; this feature can effectively defeat attempts to manipulate motor driven locking mechanisms by means of "rock-and-shake".
Bigger motors (from 2 Amps up) should not be stopped directly by short-circuit because of considerable electrical and mechanical stress imposed by this method. It is better with such motors to first short them with a shunt resistor before direct short circuit.
Such "soft-brake" is also considered in this circuit concept: With both relays being energized at the same time, both motor terminals are being connected to their respective series resistor, and its generator current will flow thru the series-impedance of these resistors and quickly slow down the rotor and other gyrating parts in a gentle way.
Since we've always using both contact-sets in parallel, we may expect the maximum switching current to be about double the rated contact current (roughly).

Endswitches (X3): The endswitches provide important information, whether the latch is fully retracted or extended. It is also possible to drive the electric motor into the blue and cut off after some seconds. But even if the mechanics can cope well with that, this would impose significant burden onto the batteries. (Timeout-method is supposed to be only 'Plan B' if there is no signal coming from the switch.)
The signal ES1/ES2 from X3 should as usual be floating or switched against circuit ground. It is recommended to have separate wiring for every end switch that is preferably shielded against motor-power, to avoid coupling.
It turned out that the relatively high-impedance of the controller's ports (around 20 kOhm) are not that problematic, since the signal is not very demanding by nature, and the Firmware can apply generous debouncing/denoising on that signal. Yet, protection of the controller from induced voltage spikes may be necessary to prevent hardware damage to the microcontroller. The block capacitors C7+C8 (100nF ceramic) provide a certain level of protection.

Keypad (X4): This is for connection of a numerical keypad (3 x 4 matrix). Note, that keypads with single contacts (13 wires) could NOT be used with this code lock.
The CodeLock firmware already provides for a comparably low multiplex frequency of only 25 Hz. However, connecting the keyboard by longer cable is not that trivial, if you want to have a secure solution. The steep, unfiltered square wave multiplex features higher frequency components (harmonics) that could in fact lead to "compromising emissions" on a longer cable. Too many hobbyist and commercial circuits don't show the slightest awareness for this vulnerability. Different with CodeLock!
The series resistors R15 to R21 not only provide portline protection but also increase line impedance that will attenuate RF harmonics of the keypad-matrix signal. In combination with basic shielding on/around the keypad, its wiring and the CodeLock assembly, it became very hard to detect anything (with amateur equipment) in a distance of more than 10 cm.
Amount of RF-blocking may be further improved by ferrite rings/chokes. For example, one could solder R15-R21 in upright position each with one additional ferrite bead.
Keyboard cable should be as short as possible, shielded or at least flat ribbon type with alternating ground lines. Unfortunately, even with all those protective measures in place, RF-specialist people may experience "frequency-selective surprise" from time to time. What looks like an exemplary EM-safe appliance up to the UHF band, could become a pity when exposed to microwave radiation.
Just saying: Stay alert!

LED (X5): The terminals provide the switched, unstabilized battery voltage (minus 0.7 V drop off T3) that may operate an Indicator-LED or keypad illumination. Current limiting resistor R12 dimensioned accordingly.

MASTER-KEY (X6): We may short this connection with a Jumper to get permanent power supply for testing purposes or programming sessions on the ATtiny (i.e. via ISP-adaptor socket). The X6 goes to the base of T3 over R8 (10 k) and is connected by D5 (BAT42) to the port input PD0 of IC1.
X6 is also intended for a MASTER-KEY when CodeLock is being used as a doorlock. In such application the numeric keypad will be located "outside", and we will need a separate button to easily activate the door-close or door-open functionality.
Well, no problem with some fancy button at X6: A short stroke on that MASTER button will regularly activate the lock and trigger "lock" functionality (if the locking mechanics was not already closed). However, a long press on this button will activate the "unlock" sequence (if the door was not already opened). To enable this, the microcontroller evaluates the button status via certain port line PD0.
It is therefore impossible to activate the "unlock" function by any activities or manipulations with keypad signals accessible from the outside. (For more details, see Firmware details).
X6 could also be activated by relay or open collector of any other control system.

Considerations regarding Phreaking / TEMPEST / RF attacks:  It's a matter of fact that security devices such as a code lock should send out none or minimum radio frequency energy as possible to disengage passive RF attacks. Else, in a very bad designed code lock, an attacker could literally "record the code entry of a legitimate user" from many meters of distance with sophisticated radio equipment and certain knowledge about the target electronics.
With active RF flooding, the attacker could remotely "illuminate" the target system with pulsed high-frequency energy (microwaves) to gain modulated echo signal by the attacked system components. Yet, with a carefully designed circuit, such attacks will not provide any significant informations because the modulation effects of various components and adjacent electronics devices will mix and interfere in a way that no distinct echo could be gained from the circuit parts and signals of interest. If, on the other hand, the attacker got physical access to the target, he could have built in kind of a passive "bug" at an appropriate place. This may be unsuspiciously lookin' "standard components" which will produce well-defined modulation when coupled with RF energy of a certain wavelength and thus send out the signal of interest into the world.
The few leaked documents about the NSA division 'ANT' indicate that spy organizations today have a wide range of radar/rf technology and standard procedures at hand to compromise target systems.
Good news is, that the same measures which inhibit RF emissions, are also effective precautions against RF-penetration. High-quality metal housing is one of the most important countermeasures. More to suggest (with focus on simple applications like code locks):

Ground connection(s):
The board layout enables isolated mounting of the CodeLock circuitry. Ground of the circuit is not necessarily tied to chassis by mounting bolts. Though it appears that such "floating" installation is only desirable in a few special situations. In most cases, it is clearly better to have a direct electrical connection of the circuit ground to the chassis at exactly one point. This provides for defined ground conditions and reduces uncontrollable interference coupling, RF emissions andsusceptibility to RF flooding. If the keypad in located in a separate metal housing with no direct connection to a common ground/chassis (like a steel door), it is of course to be explicitly grounded by the ground line provided by CodeLock PCB (GND X4-4).

Top | Index

Build it

PCB: CodeLock's circuit board data is provided in a 300-dpi-graphics which prints out to a layout of 100 x 53 mm. The files are provided in the download packet. (NOTE: As mentioned elsewhere, Julien Thomas does not support proprietary or vector formats nor does he make use of such stuff. So, please refrain from asking.)
To ensure reliable operation in a humid or corrosive environment, the whole circuit should placed either in a sealed case or protective coating should be applied at least on the solder/copper side.

These components depend on the actual voltage of battery power supply:
Relais: DIL miniature relay. Coil voltage = unstabilized battery voltage = nominal voltage of DC-motor
Tested with 6 V:
Finder 30.22.9-6V (switching current per contact up to 2A); Takamisawa RY5W-K (only small load up to 500 mA!)
Tested with 12 V:
Finder 30.22.9-12V
Since we have both sets of contacts in parallel, the rated maximum contact current will roughly double up.

Series resistor R12 (LED at X5):
For illuminated keypads, assuming maximum current of about 50 mA and green or yellow LEDs:
6V ~ 100 Ohms    /    12V ~ 220 Ohms   /  24V ~ 470 Ohms
For indicator LED only:
6V ~ 1 kOhm   /    12V ~ 2.2 kOhm     /     24V ~ 4.7 kOhm

Series Resistors / Shunts R1 + R2 (current limitation on DC-Motor, motor soft brake):
These resistors should be dimensioned by the following criteria:
provide sufficient starting current of the respective motor (and sort of "soft start" capability), and protection of battery and relays from excessive current loads in case of motor being blocked / short-circuit.
Typical values range from 2.2 ... 10 Ohms and should be rated 5 Watts at minimum.

Power Supply and motor connectors:
Connector X1 (and other connections associated with a battery pack) and connector X2 must be electrically and mechanically "rugged", i.e. capable of carrying the maximum motor current expected. Screw terminals may be used either (grid 7.5 mm).

Drilling diameters:
0.8 mm  for most electronic components; 1.0 mm  for the connectors and relays; 3,0 mm for mounting holes (M3 bolts).

Top | Index

Hall of Shame

Commercial code lock (panel)

  • Plastic all the way

  • Nasty membrane keypad

  • Annoying "acoustic feedback"

  • Mindless clock feature
    ("Hey, what time is it?" - "Wait a minute, just have a look at my safe...!" <take-off-picture-frame> )

  • Battery compartment accessible from outside - convenient and sabotage-friendly

  • Easiest access to keyhole encourages lockpicking
Commercial code lock (electronics)

  • Cheap microcontroller "EM78P447" (China/Taiwan)

  • Separate EEPROM to store codes

  • Obscure firmware

  • Maximum keylength of only 8 digits

  • Eventually has backdoors

  • Limp motor drivers (SMD crap)

  • Not really trustworthy...

Top | Index

Operating instructions "CodeLock"

ACTIVATE (general)


USER-CODE ("1234"):

* 1 2 3 4 #        = ON, confirm beeps, UNLOCK

Wrong code typed, but corrected with [*]

* 1243... * 1234 # =
ON, confirm beeps, UNLOCK

Wrong code entered (not corrected):

* 0815 #
     =   WARNINGSOUND, 8 secs blocked, OFF

LOCKING (general):


High End Number Pad "eao S.Series" [Photo: jt]
NORAD blast doors, Cheyenne Mountain, Colorado. USAF photo [License:  Public Domain, CC-PD, PD US Government]
CHANGE USER-CODE (old: "1234" /  new: "4321")

* 1234 #   = ON, confirm beeps, ÖFFNET

* 4321 #  * 4321 #  * 4321 #

or   * 4321 # 4321 # 4321 #

=  Special confirm beeps, Code changed to "4321"


If Timeout occurs before the finishing [#] has been pressed, the code will not be altered.
Entry of a code of zero-length ( [*] [#] ) will not be allowed.


* 5678 # 

= ON, Special confirm beeps, UNLOCK


Same procedure as with User-Code so far, BUT:

When CodeLock was opened by the Master-Code, this Master-Code is automatically overwriting the previous User-Code.

MASTER-KEY (electric button at X6)

SHORT keypress:

= ON, LOCK (same as with [#] on the keypad)

LONG keypress ( > 0,5 s):


Note: Any following key being pressed on the regular keypad will automatically LOCK the door again.


Key-acknowledge (0-9):   short beeps (key released)

LOCK:   long tone

ERROR:   long tone

SUCCESS:  3x short beeps

CHANGES:    9x short beeps

User-Code:     high tones

Master-Code:  lower tones

Further remarks:

CodeLock will time-out after approx. 8 seconds of inactivity (no key being pressed). Actuator will NOT move in this case.

Activation of this CodeLock will automatically LOCK the mechanism, if is was not safely locked already (depends in end switches).

Short beeps in long intervals (similar to smoke detectors with dying battery).

"CodeLock 60" = Firmware to handle one User- and one Master-Code of up to 60 decimal digits each.

Top | Index


Firmware has been written in genuine machine code (AVR-Assembler). This is to provide maximum stability, reliability and transparency. All logical and programming details are reproducible.

Top | Index


We need some random code keys for daily use?
We'd like to use hardcore stuff of a 60-digits Master-Code, yet do not feel to pound these 180+ keystrokes?

Take this, brother. May it serve you well!

The commandline tool "clkeys" generates decimal keys by means of a random function and provides preformatted output. If there was  also some Master-Code requested, the tool will deliver the EEPROM files for direct flashing into the AVR, which is facilitating the task of initially configuration of code lock.

Make random numbers

clkeys 10

64782 19503
... delivers 10-digits of User-Code (output on screen).

clkeys 10>user.txt
... forwards screen output of the program to a file named "user.txt" (in the current working directory).

clkeys 10 40 R:\security

56120 99668

15795 36519 72335 14789
99497 67493 71420 50641

Filename: R:\security

... generates User-Code of 10 digits, Master-Code of 40 digits and the following files in R:

security.bin         EEPROM data for CodeLock in binary format
security.hex         EEPROM data for CodeLock in the format Intel(R) Hex
security.txt         Same as screen output (ASCII)
For security reasons, these files should be sent directly to encrypted volume or temporarily into a Ramdisk.
The 3rd argument (filename) may be omitted. Then the programme will generate filename of current date and time.
We have option to only specify the device identifier or path, so the programme will make these three files with the unique timestamp and send them to the specified path.

See Help-Screen! (Invoke clkeys without arguments.)

Hypergeometric random numbers

With the suffix "h" or "H" directy attached to the argument of 1 and/or 2, the programme will deliver the number blocks with "hypergeometric" characteristics. That is to say:
- With 10 digits, every number's value from 0 to 9 will occur exactly once.
- With 20 digits, every number's value from 0 to 9 will occur two times - etc.

So, with the hypergeometric option, we get equidistributed occurrence of the numbers in every set of digits that is a multiple of ten.

clkeys 10H 60H

USER CODE: hyper
32519 74680

44660 21416 18642 20735
73207 94883 38579 68695
92153 78359 52040 71190

Filename: 20140404125010

Example will produce the screen output above, plus three files:

20140404125010.hex    20140404125010.txt

now with "hypergeometric" (equally distributed) random numbers.

What's the point with that hyper-hyper stuff? Well, first of all, it is desirable to have same number of keystrokes on every single key on the keypad. This is not only extending life expectancy of the mechanical parts, it's also better with regards to certain security environment. Just think of a code lock that is installed in a public area. Even if an attacker cannot spy directly while legitimate users entering their code, he could take fingerprints and find out which keys have been pressed anyway. With a too-short decimal key, only the information of which keys the code actually consists, is an effective shortcut for exhaustive code searching. It is quite obvious, that this attack won't work anymore with a 10-digits hypergeometric key code.

Of course, there is a drawback with these hypergeometrics. From a cryptographical viewpoint, they are much "weaker" compared to real random numbers of the same length. For example, with 10 digits we have:
N random decimal digits = 10N (10 ^ N) possibilities. For N = 10, keyspace is: 1010  =
N equally distributed decimal digits = N! (N-faculty). For  N = 10, keyspace is: 10*9*8*7*6*5*4*3*2*1  = 3.628.800

Of course, with longer keys, the offset is getting smaller.

Top | Index


Legal note: The "CodeLock" Project (Hardware, Software and Firmware) is a free and open documented development of Julien Thomas that's been released under the terms of Creative Commons - Attribution - Share-Alike. Anyone is free to use, modify and even commercialize this project, as long as the terms and conditions of the CC licensing deed are being observed. Most of all, the author relies on your constructive feedback to make this an even better code lock.

Top | Index



  1. Door-locking systems Elektro-Riegelsysteme (German):

  2. Want some horrific code lock?

  3. Datasheets:
    ATtiny2313 (Atmel Corporation):
    PNP switching transistor BC327:
    78L05 linear voltage regulator:

Top | Index

First published: 04/2014 ~ Last revision: 02/2016